refactor: Synchronization
This commit is contained in:
parent
fb1f2909a4
commit
bcd5b36e77
|
@ -82,6 +82,7 @@ export default (latus) => class Vulnerable extends Trait {
|
|||
}
|
||||
|
||||
destroy() {
|
||||
super.destroy();
|
||||
this.#locks.clear();
|
||||
}
|
||||
|
||||
|
@ -389,7 +390,7 @@ export default (latus) => class Vulnerable extends Trait {
|
|||
};
|
||||
}
|
||||
|
||||
packets() {
|
||||
packetsFor() {
|
||||
return this.#harms.length > 0
|
||||
? [['Harm', this.#harms.map((harm) => ({
|
||||
...harm,
|
||||
|
|
|
@ -15,7 +15,7 @@ export default () => {
|
|||
return undefined;
|
||||
}
|
||||
const onDisconnect = () => {
|
||||
synchronizer.deleteSynchronized(room.constructor.resourceId, room.s13nId());
|
||||
synchronizer.destroySynchronized(room.constructor.resourceId, room.s13nId);
|
||||
setRoom(undefined);
|
||||
};
|
||||
socket.on('disconnect', onDisconnect);
|
||||
|
@ -27,9 +27,9 @@ export default () => {
|
|||
if (!synchronizer) {
|
||||
return undefined;
|
||||
}
|
||||
const onCreated = (type, created) => {
|
||||
const onCreated = (created) => {
|
||||
const {Room} = latus.get('%resources');
|
||||
switch (type) {
|
||||
switch (created.constructor.resourceId) {
|
||||
// Track room.
|
||||
case Room.resourceId: {
|
||||
setRoom(created);
|
||||
|
|
|
@ -1,52 +1,68 @@
|
|||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import {Rectangle, Vector} from '@avocado/math';
|
||||
import {Resource} from '@avocado/resource';
|
||||
import {Synchronized} from '@avocado/s13n';
|
||||
import {Trait} from '@avocado/traits';
|
||||
import {SenderSynchronizer} from '@avocado/s13n';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
export default (latus) => class Informed extends Trait {
|
||||
export default (latus) => {
|
||||
const decorate = compose(
|
||||
Synchronized(latus),
|
||||
);
|
||||
class Synchronizer extends decorate(Resource) {}
|
||||
return class Informed extends Trait {
|
||||
|
||||
#synchronizer = new SenderSynchronizer(latus);
|
||||
#synchronizer = new Synchronizer();
|
||||
|
||||
static dependencies() {
|
||||
return [
|
||||
'Followed',
|
||||
];
|
||||
}
|
||||
static dependencies() {
|
||||
return [
|
||||
'Followed',
|
||||
];
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.#synchronizer.destroy();
|
||||
}
|
||||
destroy() {
|
||||
super.destroy();
|
||||
this.#synchronizer.destroy();
|
||||
}
|
||||
|
||||
get areaToInform() {
|
||||
// Reduce entity list to visible.
|
||||
const {camera} = this.entity;
|
||||
// Blow up camera rectangle to compensate for camera desync.
|
||||
const size = Rectangle.size(camera.rectangle);
|
||||
return Rectangle.expand(
|
||||
camera.rectangle,
|
||||
Vector.scale(size, 0.5),
|
||||
);
|
||||
}
|
||||
get areaToInform() {
|
||||
// Reduce entity list to visible.
|
||||
const {camera} = this.entity;
|
||||
// Blow up camera rectangle to compensate for camera desync.
|
||||
const size = Rectangle.size(camera.rectangle);
|
||||
return Rectangle.expand(
|
||||
camera.rectangle,
|
||||
Vector.scale(size, 0.5),
|
||||
);
|
||||
}
|
||||
|
||||
methods() {
|
||||
return {
|
||||
methods() {
|
||||
return {
|
||||
|
||||
inform: async (socket) => {
|
||||
this.#synchronizer.send(socket, this.entity);
|
||||
},
|
||||
cleanInformingPackets: () => {
|
||||
this.#synchronizer.cleanPackets();
|
||||
},
|
||||
|
||||
addSynchronized: (synchronized) => {
|
||||
this.#synchronizer.addSynchronized(synchronized);
|
||||
},
|
||||
inform: async (socket) => {
|
||||
if (socket) {
|
||||
const packets = this.#synchronizer.packetsFor(this.entity);
|
||||
if (packets.length > 0) {
|
||||
await socket.send(['Bundle', packets]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
queuePacket: (packet) => {
|
||||
this.#synchronizer.queuePacket(packet);
|
||||
},
|
||||
startInforming: (synchronized) => {
|
||||
this.#synchronizer.startSynchronizing(synchronized);
|
||||
},
|
||||
|
||||
removeSynchronized: (synchronized) => {
|
||||
this.#synchronizer.removeSynchronized(synchronized);
|
||||
},
|
||||
stopInforming: (synchronized) => {
|
||||
this.#synchronizer.stopSynchronizing(synchronized);
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
|
|
@ -111,7 +111,7 @@ export default (latus) => class Plant extends decorate(Trait) {
|
|||
};
|
||||
}
|
||||
|
||||
packets() {
|
||||
packetsFor() {
|
||||
const {growthStage} = this.stateDifferences();
|
||||
return growthStage
|
||||
? [[
|
||||
|
|
|
@ -147,6 +147,7 @@ export default (latus) => class Receptacle extends decorate(Trait) {
|
|||
}
|
||||
|
||||
destroy() {
|
||||
super.destroy();
|
||||
for (let i = 0; i < this.entity.slotCount; ++i) {
|
||||
const item = this.entity.removeItemFromSlot(i);
|
||||
if (item) {
|
||||
|
@ -292,7 +293,7 @@ export default (latus) => class Receptacle extends decorate(Trait) {
|
|||
};
|
||||
}
|
||||
|
||||
packets(informed) {
|
||||
packetsFor(informed) {
|
||||
return informed === this.entity ? this.packetUpdates : [];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import {ReceiverSynchronizer} from '@avocado/s13n';
|
||||
import {gatherWithLatus} from '@latus/core';
|
||||
|
||||
import Receiver from './receiver';
|
||||
|
||||
export default {
|
||||
hooks: {
|
||||
'@latus/http/client/up': (latus) => {
|
||||
window.latus = latus;
|
||||
const synchronizer = new ReceiverSynchronizer(latus);
|
||||
const Synchronizer = Receiver(latus);
|
||||
const synchronizer = new Synchronizer();
|
||||
latus.set('%synchronizer', synchronizer);
|
||||
latus.get('%socket').on('packet', synchronizer.acceptPacket, synchronizer);
|
||||
},
|
||||
|
|
23
packages/universe/src/client/receiver.js
Normal file
23
packages/universe/src/client/receiver.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import {Resource} from '@avocado/resource';
|
||||
import {Synchronized} from '@avocado/s13n';
|
||||
import {compose, EventEmitter} from '@latus/core';
|
||||
|
||||
export default (latus) => {
|
||||
const decorate = compose(
|
||||
EventEmitter,
|
||||
Synchronized(latus),
|
||||
);
|
||||
return class Receiver extends decorate(Resource) {
|
||||
|
||||
async acceptPacket(packet) {
|
||||
await super.acceptPacket(packet);
|
||||
const {s13nType} = packet;
|
||||
if ('create' === s13nType) {
|
||||
const {Room} = latus.get('%resources');
|
||||
const {id} = packet.data.synchronized;
|
||||
this.emit('created', this.synchronized(Room.resourceId, id));
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
};
|
|
@ -6,6 +6,10 @@ export default class Player {
|
|||
this.user = user;
|
||||
}
|
||||
|
||||
cleanInformingPackets() {
|
||||
this.entity.cleanInformingPackets();
|
||||
}
|
||||
|
||||
inform() {
|
||||
this.entity.inform(this.socket);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ export default (latus) => class Universe extends JsonResource {
|
|||
addPlayer({entity, socket, user}) {
|
||||
const room = this.room(entity.currentRoom);
|
||||
room.addEntityToLayer(entity, 0);
|
||||
entity.addSynchronized(room);
|
||||
entity.startInforming(room);
|
||||
const player = new Player({entity, socket, user});
|
||||
this.#players.push(player);
|
||||
return player;
|
||||
|
@ -41,6 +41,7 @@ export default (latus) => class Universe extends JsonResource {
|
|||
super.load(json);
|
||||
const {tps = 60, uri} = json;
|
||||
const {Room} = latus.get('%resources');
|
||||
// console.log(Object.getPrototypeOf(Object.getPrototypeOf(Room)).toString());
|
||||
if (uri) {
|
||||
const universePath = dirname(uri);
|
||||
await Promise.all(
|
||||
|
@ -72,10 +73,14 @@ export default (latus) => class Universe extends JsonResource {
|
|||
for (let i = 0; i < this.#players.length; ++i) {
|
||||
promises.push(this.#players[i].inform());
|
||||
}
|
||||
// TODO: rogue client?
|
||||
await Promise.all(promises);
|
||||
for (let i = 0; i < this.#roomsFlat.length; i++) {
|
||||
this.#roomsFlat[i].cleanPackets();
|
||||
}
|
||||
for (let i = 0; i < this.#players.length; ++i) {
|
||||
this.#players[i].cleanInformingPackets();
|
||||
}
|
||||
}
|
||||
|
||||
static async load(json = {}) {
|
||||
|
@ -88,7 +93,7 @@ export default (latus) => class Universe extends JsonResource {
|
|||
removePlayer(player) {
|
||||
const {entity} = player;
|
||||
const room = this.room(entity.currentRoom);
|
||||
entity.removeSynchronized(room);
|
||||
entity.stopInforming(room);
|
||||
room.removeEntityFromLayer(entity, 0);
|
||||
const index = this.#players.indexOf(player);
|
||||
if (-1 !== index) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user