mirror of
https://github.com/nasa/openmct.git
synced 2024-12-19 05:07:52 +00:00
[Layout] Layout rebuilds after resize/reposition - Fixed potential race condition #32
This commit is contained in:
parent
424953c894
commit
db7224486c
@ -45,7 +45,8 @@ define(
|
||||
* @param {Scope} $scope the controller's Angular scope
|
||||
*/
|
||||
function LayoutController($scope) {
|
||||
var self = this;
|
||||
var self = this,
|
||||
callbackCount = 0;
|
||||
|
||||
// Update grid size when it changed
|
||||
function updateGridSize(layoutGrid) {
|
||||
@ -91,23 +92,26 @@ define(
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
function getComposition(domainObject){
|
||||
return domainObject.useCapability('composition');
|
||||
}
|
||||
|
||||
function composeView (composition){
|
||||
$scope.composition = composition;
|
||||
return composition.map(function (object) {
|
||||
return object.getId();
|
||||
}) || [];
|
||||
}
|
||||
|
||||
//Will fetch fully contextualized composed objects, and populate
|
||||
// scope with them.
|
||||
function refreshComposition(ids) {
|
||||
return getComposition($scope.domainObject)
|
||||
.then(composeView)
|
||||
.then(function(ids){self.layoutPanels(ids);});
|
||||
function refreshComposition() {
|
||||
//Keep a track of how many composition callbacks have been made
|
||||
var thisCount = ++callbackCount;
|
||||
|
||||
$scope.domainObject.useCapability('composition').then(function(composition){
|
||||
var ids;
|
||||
|
||||
//Is this callback for the most recent composition
|
||||
// request? If not, discard it. Prevents race condition
|
||||
if (thisCount === callbackCount){
|
||||
ids = composition.map(function (object) {
|
||||
return object.getId();
|
||||
}) || [];
|
||||
|
||||
$scope.composition = composition;
|
||||
self.layoutPanels(ids);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// End drag; we don't want to put $scope into this
|
||||
|
@ -33,7 +33,8 @@ define(
|
||||
testConfiguration,
|
||||
controller,
|
||||
mockCompositionCapability,
|
||||
mockComposition;
|
||||
mockComposition,
|
||||
mockCompositionObjects;
|
||||
|
||||
function mockPromise(value){
|
||||
return {
|
||||
@ -67,6 +68,7 @@ define(
|
||||
testModel = {};
|
||||
|
||||
mockComposition = ["a", "b", "c"];
|
||||
mockCompositionObjects = mockComposition.map(mockDomainObject);
|
||||
|
||||
testConfiguration = {
|
||||
panels: {
|
||||
@ -77,7 +79,7 @@ define(
|
||||
}
|
||||
};
|
||||
|
||||
mockCompositionCapability = mockPromise(mockComposition.map(mockDomainObject));
|
||||
mockCompositionCapability = mockPromise(mockCompositionObjects);
|
||||
|
||||
mockScope.domainObject = mockDomainObject("mockDomainObject");
|
||||
mockScope.model = testModel;
|
||||
@ -107,6 +109,30 @@ define(
|
||||
);
|
||||
});
|
||||
|
||||
it("Is robust to concurrent changes to composition", function () {
|
||||
var secondMockComposition = ["a", "b", "c", "d"],
|
||||
secondMockCompositionObjects = secondMockComposition.map(mockDomainObject),
|
||||
firstCompositionCB,
|
||||
secondCompositionCB;
|
||||
|
||||
spyOn(mockCompositionCapability, "then");
|
||||
mockScope.$watchCollection.mostRecentCall.args[1]();
|
||||
mockScope.$watchCollection.mostRecentCall.args[1]();
|
||||
|
||||
firstCompositionCB = mockCompositionCapability.then.calls[0].args[0];
|
||||
secondCompositionCB = mockCompositionCapability.then.calls[1].args[0];
|
||||
|
||||
//Resolve promises in reverse order
|
||||
secondCompositionCB(secondMockCompositionObjects);
|
||||
firstCompositionCB(mockCompositionObjects);
|
||||
|
||||
//Expect the promise call that was initiated most recently to
|
||||
// be the one used to populate scope, irrespective of order that
|
||||
// it was eventually resolved
|
||||
expect(mockScope.composition).toBe(secondMockCompositionObjects);
|
||||
});
|
||||
|
||||
|
||||
it("provides styles for frames, from configuration", function () {
|
||||
mockScope.$watchCollection.mostRecentCall.args[1]();
|
||||
expect(controller.getFrameStyle("a")).toEqual({
|
||||
|
Loading…
Reference in New Issue
Block a user