Our application reads CZML data sources and updates the associated DynamicObjects once they are created and populated with the properties included in the czml (e.g. path, label, etc…).
Until version B20, the way we did it was to subscribe to the “objectPropertiesChanged” of the CzmlDataSource DynamicObjectCollection.
With the refactoring done in B21 in DynamicObjectCollection, the event “objectPropertiesChanged” has been removed and another one “collectionChanged” has been added.
We replaced the code using the new event expecting to have a similar result but we saw that the event is called but all the properties of the dynamicObject were empty.
Looking at the CzmlDataSource code “processCzmlPacket” method, the dynamicObject is created first by calling “getOrCreateObject”, which triggers the “collectionChanged” event. However, the updater functions,
which populate the object with all the rest of Czml packet data, are called later. The effect is that the collectionChanged event will be called with an empty dynamicObject.
Should CzmlDataSource add the dynamicObject once is fully parsed so the event can be used for this type of purposes or is there a better way for doing this post loading processing?
Each DynamicObject now has a
propertyChanged event that you can subscribe to from within your
collectionChanged event listener. That event will be raised as each property gets loaded into the DynamicObject, or if a property later changes “type”, for example, if a ConstantProperty is replaced by a SampledProperty, or even if a ConstantProperty is replaced by a new ConstantProperty with a new value.
The parameters passed to the
propertyChanged listeners are (dynamicObject, propertyName, newProperty, oldProperty).
However, in your case, if you’re just loading a single CZML file into a DynamicObjectCollection, you might find it easier to make your changes to the DynamicObjects by simply calling
getObjects() on the collection after you’ve finished loading the CZML, and then iterating through the dynamic objects and change whatever you need to change. The event-driven approach makes more sense if you are maintaining a single DynamicObjectCollection, and you are repeatedly loading new documents or adding additional documents into that collection.
Thanks for your reply Scott,
I have tried your suggestion adding a “propertyChanged” listener to each dynamicObject loaded.
As you say the event is generated when a property (e.g. Label) is changed (e.g. to a DynamicLabel).
What I see is that the event is generated when the DynamicLabel is created (empty) from Czml packet (line 908 CzmlDataSource), not when all the properties are loaded (successive calls to processPacketData for the DynamicLabel).
Therefore when the propertyChanged is raised the DynamicLabel is always an empty one, and whatever change I do at that time will be overwriten by Czml processing. No other events are generated for the changes within the DynamicLabel (e.g. color, text, etc…).
I believe that this is the desired behaviour after the refactoring, and there is no event bubbling for the properties of the dynamicObject.
If I want to be notified of changes within the inner properties of a dynamicObject I would need to add yet another listener for each property (e.g. DynamicLabel), correct?
Many thanks for your help and clarifications,
What you might want to listen to is the changed event from CZMLDataSource.getChangedEvent().
This event will be raised at the end of CZML processing so all data will be loaded.