Skip to content

Commit

Permalink
Make property notification and CompositeEntityCollection work.
Browse files Browse the repository at this point in the history
  • Loading branch information
kring committed Jan 18, 2017
1 parent cb739c4 commit 96a288d
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 2 deletions.
104 changes: 104 additions & 0 deletions Source/DataSources/ArbitraryProperties.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*global define*/
define([
'../Core/defaultValue',
'../Core/defined',
'../Core/defineProperties',
'../Core/DeveloperError',
'../Core/Event',
'./createMaterialPropertyDescriptor',
'./createPropertyDescriptor'
], function(
defaultValue,
defined,
defineProperties,
DeveloperError,
Event,
createMaterialPropertyDescriptor,
createPropertyDescriptor) {
'use strict';

/**
* Describes arbitrary properties of an {@link Entity}.
*
* @alias ArbitraryProperties
* @constructor
*
* @param {Object} [options] Object with arbitrary properties to assign to this instance.
*
* @see Entity
*/
function ArbitraryProperties(options) {
this._definitionChanged = new Event();
this._propertyNames = [];
this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT));
}

defineProperties(ArbitraryProperties.prototype, {
/**
* Gets the event that is raised whenever a property or sub-property is changed or modified.
* @memberof ArbitraryProperties.prototype
* @type {Event}
* @readonly
*/
definitionChanged : {
get : function() {
return this._definitionChanged;
}
}
});

/**
* Duplicates this instance.
*
* @param {ArbitraryProperties} [result] The object onto which to store the result.
* @returns {ArbitraryProperties} The modified result parameter or a new instance if one was not provided.
*/
ArbitraryProperties.prototype.clone = function(result) {
if (!defined(result)) {
result = new ArbitraryProperties();
}

for (var i = 0; i < this._propertyNames.length; ++i) {
var propertyName = this._propertyNames[i];
result.addProperty(propertyName);
result[propertyName] = this[propertyName];
}

return result;
};

/**
* Assigns each unassigned property on this object to the value
* of the same property on the provided source object.
*
* @param {ArbitraryProperties} source The object to be merged into this object.
*/
ArbitraryProperties.prototype.merge = function(source) {
//>>includeStart('debug', pragmas.debug);
if (!defined(source)) {
throw new DeveloperError('source is required.');
}
//>>includeEnd('debug');

var propertyNames = source._propertyNames || Object.keys(source);
for (var i = 0; i < propertyNames.length; ++i) {
var propertyName = propertyNames[i];
this.addProperty(propertyName);
this[propertyName] = defaultValue(this[propertyName], source[propertyName]);
}
};

/**
* Adds a property if it doesn't already exist. If it does exist, this function does nothing.
*
* @param {String} propertyName The name of the property to add.
*/
ArbitraryProperties.prototype.addProperty = function(propertyName) {
if (!defined(Object.getOwnPropertyDescriptor(this, propertyName))) {
Object.defineProperty(this, propertyName, createPropertyDescriptor(propertyName));
this._propertyNames.push(propertyName);
}
};

return ArbitraryProperties;
});
5 changes: 4 additions & 1 deletion Source/DataSources/CzmlDataSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ define([
'../Scene/VerticalOrigin',
'../ThirdParty/Uri',
'../ThirdParty/when',
'./ArbitraryProperties',
'./BillboardGraphics',
'./BoxGraphics',
'./ColorMaterialProperty',
Expand Down Expand Up @@ -127,6 +128,7 @@ define([
VerticalOrigin,
Uri,
when,
ArbitraryProperties,
BillboardGraphics,
BoxGraphics,
ColorMaterialProperty,
Expand Down Expand Up @@ -992,14 +994,15 @@ define([
var propertiesData = packet.properties;
if (defined(propertiesData)) {
if (!defined(entity.properties)) {
entity.properties = {};
entity.properties = new ArbitraryProperties();
}
var key;
//We cannot simply call processPacketData(entity, 'properties', propertyData, undefined, sourceUri, entityCollection)
//because each property of "properties" may vary separately.
//The properties will be accessible as entity.properties.myprop.getValue(time).
for (key in propertiesData) {
if (propertiesData.hasOwnProperty(key)) {
entity.properties.addProperty(key);
processPacketData(Object, entity.properties, key, propertiesData[key], undefined, sourceUri, entityCollection);
}
}
Expand Down
13 changes: 12 additions & 1 deletion Source/DataSources/Entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ define([
'../Core/Matrix4',
'../Core/Quaternion',
'../Core/Transforms',
'./ArbitraryProperties',
'./BillboardGraphics',
'./BoxGraphics',
'./ConstantPositionProperty',
Expand Down Expand Up @@ -42,6 +43,7 @@ define([
Matrix4,
Quaternion,
Transforms,
ArbitraryProperties,
BillboardGraphics,
BoxGraphics,
ConstantPositionProperty,
Expand Down Expand Up @@ -109,6 +111,7 @@ define([
* @param {PointGraphics} [options.point] A point to associate with this entity.
* @param {PolygonGraphics} [options.polygon] A polygon to associate with this entity.
* @param {PolylineGraphics} [options.polyline] A polyline to associate with this entity.
* @param {ArbitraryProperties} [options.properties] Arbitrary properties to associate with this entity.
* @param {PolylineVolumeGraphics} [options.polylineVolume] A polylineVolume to associate with this entity.
* @param {RectangleGraphics} [options.rectangle] A rectangle to associate with this entity.
* @param {WallGraphics} [options.wall] A wall to associate with this entity.
Expand All @@ -131,7 +134,7 @@ define([
this._parent = undefined;
this._propertyNames = ['billboard', 'box', 'corridor', 'cylinder', 'description', 'ellipse', //
'ellipsoid', 'label', 'model', 'orientation', 'path', 'point', 'polygon', //
'polyline', 'polylineVolume', 'position', 'rectangle', 'viewFrom', 'wall'];
'polyline', 'polylineVolume', 'position', 'properties', 'rectangle', 'viewFrom', 'wall'];

this._billboard = undefined;
this._billboardSubscription = undefined;
Expand Down Expand Up @@ -165,6 +168,8 @@ define([
this._polylineVolumeSubscription = undefined;
this._position = undefined;
this._positionSubscription = undefined;
this._properties = undefined;
this._propertiesSubscription = undefined;
this._rectangle = undefined;
this._rectangleSubscription = undefined;
this._viewFrom = undefined;
Expand Down Expand Up @@ -416,6 +421,12 @@ define([
* @type {PolylineVolumeGraphics}
*/
polylineVolume : createPropertyTypeDescriptor('polylineVolume', PolylineVolumeGraphics),
/**
* Gets or sets the bag of arbitrary properties associated with this entity.
* @memberof Entity.prototype
* @type {Object}
*/
properties : createPropertyTypeDescriptor('properties', ArbitraryProperties),
/**
* Gets or sets the position.
* @memberof Entity.prototype
Expand Down
80 changes: 80 additions & 0 deletions Specs/DataSources/CzmlDataSourceSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ defineSuite([
'Core/Spherical',
'Core/TimeInterval',
'Core/TranslationRotationScale',
'DataSources/CompositeEntityCollection',
'DataSources/EntityCollection',
'DataSources/ReferenceProperty',
'DataSources/StripeOrientation',
Expand Down Expand Up @@ -59,6 +60,7 @@ defineSuite([
Spherical,
TimeInterval,
TranslationRotationScale,
CompositeEntityCollection,
EntityCollection,
ReferenceProperty,
StripeOrientation,
Expand Down Expand Up @@ -1523,6 +1525,84 @@ defineSuite([
expect(entity.properties.changing_array.getValue(time2)).toEqual(array2);
});

it('handles properties in a way that allows CompositeEntityCollection to work', function() {
var testObject1 = {
foo: 4,
bar: {
name: 'bar'
}
};
var testArray1 = [2, 4, 16, 'test'];
var packet1 = {
id: 'test',
properties: {
constant_name: 'ABC',
constant_height: 8,
constant_object: {
value: testObject1
},
constant_array: {
value: testArray1
}
}
};

var dataSource1 = new CzmlDataSource();
dataSource1.load(makePacket(packet1));

var dataSource2 = new CzmlDataSource();
var composite = new CompositeEntityCollection([dataSource1.entities, dataSource2.entities]);

// Initially we use all the properties from dataSource1.
var entity = composite.values[0];
expect(entity.properties.constant_name.getValue(Iso8601.MINIMUM_VALUE)).toEqual(packet1.properties.constant_name);
expect(entity.properties.constant_height.getValue(Iso8601.MINIMUM_VALUE)).toEqual(packet1.properties.constant_height);
expect(entity.properties.constant_object.getValue(Iso8601.MINIMUM_VALUE)).toEqual(testObject1);
expect(entity.properties.constant_array.getValue(Iso8601.MINIMUM_VALUE)).toEqual(testArray1);

// Load a new packet into dataSource2 and it should take precedence in the composite.
var packet2 = {
id: 'test',
properties: {
constant_name: 'DEF'
}
};

dataSource2.load(makePacket(packet2));

entity = composite.values[0];
expect(entity.properties.constant_name.getValue(Iso8601.MINIMUM_VALUE)).toEqual(packet2.properties.constant_name);
expect(entity.properties.constant_height.getValue(Iso8601.MINIMUM_VALUE)).toEqual(packet1.properties.constant_height);
expect(entity.properties.constant_object.getValue(Iso8601.MINIMUM_VALUE)).toEqual(testObject1);
expect(entity.properties.constant_array.getValue(Iso8601.MINIMUM_VALUE)).toEqual(testArray1);

// Changed values should be mirrored in the composite, too.
var testObject3 = {
some: 'value'
};
var testArray3 = ['not', 'the', 'same', 4];
var packet3 = {
id: 'test',
properties: {
constant_height: 9,
constant_object: {
value: testObject3
},
constant_array: {
value: testArray3
}
}
};

dataSource2.process(packet3);

entity = composite.values[0];
expect(entity.properties.constant_name.getValue(Iso8601.MINIMUM_VALUE)).toEqual(packet2.properties.constant_name);
expect(entity.properties.constant_height.getValue(Iso8601.MINIMUM_VALUE)).toEqual(packet3.properties.constant_height);
expect(entity.properties.constant_object.getValue(Iso8601.MINIMUM_VALUE)).toEqual(testObject3);
expect(entity.properties.constant_array.getValue(Iso8601.MINIMUM_VALUE)).toEqual(testArray3);
});

it('CZML Availability works with a single interval.', function() {
var packet1 = {
id : 'testObject',
Expand Down

0 comments on commit 96a288d

Please sign in to comment.