Skip to content

Commit

Permalink
Merge remote-tracking branch 'mozilla/master' into merge-mozilla-changes
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentfretin committed Feb 27, 2021
2 parents 73f9fa7 + ff4f0e9 commit 393ec7b
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 28 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ jspm_packages

# MacOS
.DS_Store
**Icon?

# Testing suites
errorShots
Expand Down
5 changes: 4 additions & 1 deletion src/NetworkConnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,10 @@ class NetworkConnection {

disconnect() {
this.entities.removeRemoteEntities();
this.adapter.disconnect();

if (this.adapter) {
this.adapter.disconnect();
}

NAF.app = '';
NAF.room = '';
Expand Down
29 changes: 13 additions & 16 deletions src/NetworkEntities.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ class NetworkEntities {
var networkId = entityData.networkId;
var el = NAF.schemas.getCachedTemplate(entityData.template);

el.setAttribute('id', 'naf-' + networkId);

this.initPosition(el, entityData.components);
this.initRotation(el, entityData.components);
this.addNetworkComponent(el, entityData);
Expand Down Expand Up @@ -73,7 +71,7 @@ class NetworkEntities {

if (this.hasEntity(networkId)) {
this.entities[networkId].components.networked.networkUpdate(entityData);
} else if (entityData.isFirstSync) {
} else if (entityData.isFirstSync && NAF.connection.activeDataChannels[entityData.owner] !== false) {
if (NAF.options.firstSyncSource && source !== NAF.options.firstSyncSource) {
NAF.log.write('Ignoring first sync from disallowed source', source);
} else {
Expand Down Expand Up @@ -132,8 +130,7 @@ class NetworkEntities {
}

addEntityToParent(entity, parentId) {
var parentEl = document.getElementById('naf-' + parentId);
parentEl.appendChild(entity);
this.entities[parentId].appendChild(entity);
}

addEntityToSceneRoot(el) {
Expand All @@ -156,22 +153,22 @@ class NetworkEntities {
}

removeEntitiesOfClient(clientId) {
var entityList = [];
const removedEntities = [];
for (var id in this.entities) {
var entityCreator = NAF.utils.getCreator(this.entities[id]);
if (entityCreator === clientId) {
let persists;
const component = this.entities[id].getAttribute('networked');
const entity = this.entities[id]
const creator = NAF.utils.getCreator(entity);
const owner = NAF.utils.getNetworkOwner(entity);
if (creator === clientId || (!creator && owner === clientId)) {
const component = this.entities[id].getAttribute("networked")
if (component && component.persistent) {
persists = NAF.utils.takeOwnership(this.entities[id]);
}
if (!persists) {
var entity = this.removeEntity(id);
entityList.push(entity);
// everyone will attempt to take ownership, someone will win, it does not particularly matter who
NAF.utils.takeOwnership(entity);
} else {
removedEntities.push(this.removeEntity(id));
}
}
}
return entityList;
return removedEntities;
}

removeEntity(id) {
Expand Down
80 changes: 73 additions & 7 deletions src/components/networked.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,49 @@ function defaultRequiresUpdate() {
};
}

function isValidVector3(v) {
return !!(
v.isVector3 &&
!isNaN(v.x) &&
!isNaN(v.y) &&
!isNaN(v.z) &&
v.x !== null &&
v.y !== null &&
v.z !== null
);
}
function isValidQuaternion(q) {
return !!(
q.isQuaternion &&
!isNaN(q.x) &&
!isNaN(q.y) &&
!isNaN(q.z) &&
!isNaN(q.w) &&
q.x !== null &&
q.y !== null &&
q.z !== null &&
q.w !== null
);
}

var throttle = (function () {
var previousLogTime = 0;
return function throttle(f, milliseconds) {
var now = Date.now();
if (now - previousLogTime > milliseconds) {
previousLogTime = now;
f();
}
};
})();

function warnOnInvalidNetworkUpdate() {
NAF.log.warn(`Received invalid network update.`);
}

AFRAME.registerSystem("networked", {
init() {
// An array of "networked" component instances.
this.components = [];
this.nextSyncTime = 0;
},
Expand All @@ -41,6 +82,7 @@ AFRAME.registerSystem("networked", {
if (!NAF.connection.adapter) return;
if (this.el.clock.elapsedTime < this.nextSyncTime) return;

// "d" is an array of entity datas per entity in this.components.
const data = { d: [] };

for (let i = 0, l = this.components.length; i < l; i++) {
Expand Down Expand Up @@ -118,8 +160,17 @@ AFRAME.registerComponent('networked', {

this.initNetworkParent();

let networkId;

if (this.data.networkId === '') {
this.el.setAttribute(this.name, {networkId: NAF.utils.createNetworkId()});
networkId = NAF.utils.createNetworkId()
this.el.setAttribute(this.name, {networkId});
} else {
networkId = this.data.networkId;
}

if (!this.el.id) {
this.el.setAttribute('id', 'naf-' + networkId);
}

if (wasCreatedByNetwork) {
Expand Down Expand Up @@ -246,14 +297,29 @@ AFRAME.registerComponent('networked', {
var object3D = bufferInfo.object3D;
var componentNames = bufferInfo.componentNames;
buffer.update(dt);
if (componentNames.includes('position')) {
object3D.position.copy(buffer.getPosition());
if (componentNames.includes("position")) {
const position = buffer.getPosition();
if (isValidVector3(position)) {
object3D.position.copy(position);
} else {
throttle(warnOnInvalidNetworkUpdate, 5000);
}
}
if (componentNames.includes('rotation')) {
object3D.quaternion.copy(buffer.getQuaternion());
if (componentNames.includes("rotation")) {
const quaternion = buffer.getQuaternion();
if (isValidQuaternion(quaternion)) {
object3D.quaternion.copy(quaternion);
} else {
throttle(warnOnInvalidNetworkUpdate, 5000);
}
}
if (componentNames.includes('scale')) {
object3D.scale.copy(buffer.getScale());
if (componentNames.includes("scale")) {
const scale = buffer.getScale();
if (isValidVector3(scale)) {
object3D.scale.copy(scale);
} else {
throttle(warnOnInvalidNetworkUpdate, 5000);
}
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ module.exports.isMine = function(entity) {
throw new Error("Entity does not have and is not a child of an entity with the [networked] component ");
}

// When remote networked entities are initially created, there's a frame delay before they are completely instantiated.
// On that frame, data is undefined so we can't check the owner. In this instance we assume that the user is not the owner of the entity.
if (!curEntity.components.networked.data) {
return false;
}

return curEntity.components.networked.data.owner === NAF.clientId;
};

Expand Down
8 changes: 5 additions & 3 deletions tests/unit/networked.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ suite('networked', function() {
assets: [
"<template id='t1'><a-entity><a-entity class='template-child'></a-entity></a-entity></template>"
],
entity: '<a-entity id="test-entity" networked="template:#t1" position="1 2 3" rotation="4 3.5 2"><a-box></a-box></a-entity>'
entity: '<a-entity networked="template:#t1" position="1 2 3" rotation="4 3.5 2"><a-box></a-box></a-entity>'
};
scene = helpers.sceneFactory(opts);
naf.utils.whenEntityLoaded(scene, done);
Expand All @@ -26,7 +26,7 @@ suite('networked', function() {
naf.clientId = 'owner1';
naf.connection.setNetworkAdapter(new helpers.MockNetworkAdapter());
initScene(function() {
entity = document.querySelector('#test-entity');
entity = document.querySelector('a-entity');
networked = entity.components['networked'];
networkedSystem = scene.systems['networked'];
networked.data.networkId = '';
Expand All @@ -51,13 +51,15 @@ suite('networked', function() {

suite('init', function() {

test('sets networkId', sinon.test(function() {
test('sets networkId and element id', sinon.test(function() {
this.stub(naf.utils, 'createNetworkId').returns('nid1');

networked.el.id = ''
networked.init();

var result = networked.data.networkId;
assert.equal(result, 'nid1');
assert.equal(entity.id, 'naf-nid1');
}));

test('retains networkId after component update', sinon.test(function() {
Expand Down

0 comments on commit 393ec7b

Please sign in to comment.