diff --git a/packages/entity/list/index.js b/packages/entity/list/index.js index 000f163..2aed160 100644 --- a/packages/entity/list/index.js +++ b/packages/entity/list/index.js @@ -1,5 +1,9 @@ import {compose, EventEmitter} from '@avocado/core'; import {QuadTree, Rectangle, Vector} from '@avocado/math'; +import { + SynchronizedCreatePacket, + SynchronizedDestroyPacket, +} from '@avocado/net'; import {EntityListUpdateEntityPacket} from '../packets/entity-list-update-entity.packet'; import {Entity} from '../entity.synchronized'; @@ -14,10 +18,9 @@ export class EntityList extends decorate(class {}) { super(); this._afterDestructionTickers = []; this._entities = {}; - this._entitiesJustAdded = []; - this._entitiesJustRemoved = []; this._entityTickers = [] this._flatEntities = []; + this._informedEntities = new Map(); this._quadTree = new QuadTree(); } @@ -41,6 +44,16 @@ export class EntityList extends decorate(class {}) { } } } + if (packet instanceof SynchronizedCreatePacket) { + const entity = new Entity(packet.data.spec); + this.addEntity(entity); + } + if (packet instanceof SynchronizedDestroyPacket) { + const uuid = packet.data.synchronized.id; + if (this._entities[uuid]) { + this._entities[uuid].destroy(); + } + } } addEntity(entity) { @@ -53,7 +66,7 @@ export class EntityList extends decorate(class {}) { this._flatEntities.push(entity); this._entityTickers.push(entity.tick); if (AVOCADO_SERVER) { - this._entitiesJustAdded.push(entity); + this._informedEntities.set(entity, []); } entity.setIntoList(this); entity.once('destroy', () => { @@ -103,17 +116,38 @@ export class EntityList extends decorate(class {}) { packets(informed) { const packets = []; + // Visible entities. + const {areaToInform} = informed; + const previousVisibleEntities = this._informedEntities.get(informed); + const visibleEntities = this.visibleEntities(areaToInform); const updates = []; - for (const uuid in this._entities) { - const entity = this._entities[uuid]; - const entityPackets = entity.packets(informed); - if (entityPackets.length > 0) { - updates.push({ - uuid: entity.instanceUuid, - packets: entityPackets, - }); + for (let i = 0; i < visibleEntities.length; i++) { + const entity = visibleEntities[i]; + // Newly visible entity. + const index = previousVisibleEntities.indexOf(entity); + if (-1 === index) { + packets.push(entity.createPacket(informed)); + } + // Still visible entity. + else { + const entityPackets = entity.packets(informed); + if (entityPackets.length > 0) { + updates.push({ + uuid: entity.instanceUuid, + packets: entityPackets, + }); + } + previousVisibleEntities.splice(index, 1); } } + for (let i = 0; i < previousVisibleEntities.length; i++) { + const entity = previousVisibleEntities[i]; + // Newly removed entity. + if (-1 === visibleEntities.indexOf(entity)) { + packets.push(entity.destroyPacket(informed)); + } + } + this._informedEntities.set(informed, visibleEntities); if (updates.length > 0) { packets.push(new EntityListUpdateEntityPacket(updates)); } @@ -130,7 +164,7 @@ export class EntityList extends decorate(class {}) { return; } if (AVOCADO_SERVER) { - this._entitiesJustRemoved.push(entity); + this._informedEntities.delete(entity); } entity.removeFromList(); delete this._entities[uuid]; diff --git a/packages/net/s13n/server.js b/packages/net/s13n/server.js index 6b572b7..50780e7 100644 --- a/packages/net/s13n/server.js +++ b/packages/net/s13n/server.js @@ -1,4 +1,4 @@ -import {idFromSynchronized, synchronizedFromId} from './registry'; +import {idFromSynchronized} from './registry'; import {SynchronizedCreatePacket} from './synchronized-create.packet'; import {SynchronizedDestroyPacket} from './synchronized-destroy.packet'; @@ -52,28 +52,15 @@ export class ServerSynchronizer { const payload = []; for (let i = 0; i < this._synchronizedFlat.length; i++) { const synchronized = this._synchronizedFlat[i]; - const id = synchronized.synchronizationId(); - const type = idFromSynchronized(synchronized.constructor); if (-1 !== this._added.indexOf(synchronized)) { - const packet = new SynchronizedCreatePacket({ - synchronized: { - id, - type, - }, - spec: synchronized.toNetwork(informed), - }); - payload.push(packet); + payload.push(synchronized.createPacket(informed)); } else if (-1 !== this._removed.indexOf(synchronized)) { - const packet = new SynchronizedDestroyPacket({ - synchronized: { - id, - type, - }, - }); - payload.push(packet); + payload.push(synchronized.destroyPacket(informed)); } else { + const id = synchronized.synchronizationId(); + const type = idFromSynchronized(synchronized.constructor); const packets = synchronized.packetsFor(informed); for (let j = 0; j < packets.length; j++) { const packet = packets[j]; diff --git a/packages/net/s13n/synchronized.js b/packages/net/s13n/synchronized.js index 1b081e1..fa7f823 100644 --- a/packages/net/s13n/synchronized.js +++ b/packages/net/s13n/synchronized.js @@ -1,3 +1,7 @@ +import {idFromSynchronized} from './registry'; +import {SynchronizedCreatePacket} from './synchronized-create.packet'; +import {SynchronizedDestroyPacket} from './synchronized-destroy.packet'; + export function SynchronizedMixin(Superclass) { return class Synchronized extends Superclass { @@ -11,8 +15,31 @@ export function SynchronizedMixin(Superclass) { this._idempotentPackets = []; } + createPacket(informed) { + const id = this.synchronizationId(); + const type = idFromSynchronized(this.constructor); + return new SynchronizedCreatePacket({ + synchronized: { + id, + type, + }, + spec: this.toNetwork(informed), + }); + } + destroy() {} + destroyPacket(informed) { + const id = this.synchronizationId(); + const type = idFromSynchronized(this.constructor); + return new SynchronizedDestroyPacket({ + synchronized: { + id, + type, + }, + }); + } + fromNetwork(json) { this.fromJSON(json); } diff --git a/packages/topdown/layer.js b/packages/topdown/layer.js index f206c65..8885731 100644 --- a/packages/topdown/layer.js +++ b/packages/topdown/layer.js @@ -5,6 +5,10 @@ import { EntityListUpdateEntityPacket, } from '@avocado/entity'; import {Vector} from '@avocado/math'; +import { + SynchronizedCreatePacket, + SynchronizedDestroyPacket, +} from '@avocado/net'; import {ShapeList} from '@avocado/physics'; import { @@ -57,6 +61,13 @@ export class Layer extends decorate(class {}) { if (packet instanceof EntityListUpdateEntityPacket) { this.entityList.acceptPacket(packet); } + // May have to check type... + if (packet instanceof SynchronizedCreatePacket) { + this.entityList.acceptPacket(packet); + } + if (packet instanceof SynchronizedDestroyPacket) { + this.entityList.acceptPacket(packet); + } } addEntity(entity) {