diff --git a/platform/features/plot/src/elements/PlotUpdater.js b/platform/features/plot/src/elements/PlotUpdater.js index dd7a690989..ed81035b6b 100644 --- a/platform/features/plot/src/elements/PlotUpdater.js +++ b/platform/features/plot/src/elements/PlotUpdater.js @@ -21,7 +21,7 @@ define( * @param {string} domain the key to use when looking up domain values * @param {string} range the key to use when looking up range values */ - function PlotUpdater(subscription, domain, range) { + function PlotUpdater(subscription, domain, range, maxPoints) { var max = [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY], min = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY], x, @@ -46,12 +46,12 @@ define( // Check if we don't have enough room if (index > (buffer.length / 2 - 1)) { // If we don't, can we expand? - if (index < MAX_POINTS) { + if (index < maxPoints) { // Double the buffer size buffer = buffers[id] = doubleSize(buffer); } else { // Just shift the existing buffer - buffer.copyWithin(0, 2); + buffer.set(buffer.subarray(2)); } } @@ -82,12 +82,12 @@ define( // Ensure there is space for the new buffer buffer = ensureBufferSize(buffer, id, index); // Account for shifting that may have occurred - index = Math.min(index, MAX_POINTS - 2); + index = Math.min(index, maxPoints - 1); // Update the buffer buffer[index * 2] = domainValue - domainOffset; buffer[index * 2 + 1] = rangeValue; // Update length - lengths[id] = Math.min(index + 1, MAX_POINTS); + lengths[id] = Math.min(index + 1, maxPoints); // Observe max/min range values max[1] = Math.max(max[1], rangeValue); min[1] = Math.min(min[1], rangeValue); @@ -130,6 +130,9 @@ define( bufferArray.push(buffers[id]); } + // Use a default MAX_POINTS if none is provided + maxPoints = maxPoints || MAX_POINTS; + // Initially prepare state for these objects. // Note that this may be an empty array at this time, // so we also need to check during update cycles. diff --git a/platform/features/plot/test/elements/PlotUpdaterSpec.js b/platform/features/plot/test/elements/PlotUpdaterSpec.js index a8e10049a0..41be699578 100644 --- a/platform/features/plot/test/elements/PlotUpdaterSpec.js +++ b/platform/features/plot/test/elements/PlotUpdaterSpec.js @@ -49,7 +49,8 @@ define( updater = new PlotUpdater( mockSubscription, testDomain, - testRange + testRange, + 1350 // Smaller max size for easier testing ); }); @@ -66,7 +67,7 @@ define( it("maintains a buffer of received telemetry", function () { // Count should be large enough to trigger a buffer resize - var count = 1000, + var count = 750, i; // Increment values exposed by subscription @@ -107,6 +108,54 @@ define( } }); + it("can handle delayed telemetry object availability", function () { + // The case can occur where getTelemetryObjects() returns an + // empty array - specifically, while objects are still being + // loaded. The updater needs to be able to cope with that + // case. + var tmp = mockSubscription.getTelemetryObjects(); + mockSubscription.getTelemetryObjects.andReturn([]); + + // Reinstantiate with the empty subscription + updater = new PlotUpdater( + mockSubscription, + testDomain, + testRange + ); + + // Should have 0 buffers for 0 objects + expect(updater.getBuffers().length).toEqual(0); + + // Restore the three objects the test subscription would + // normally have. + mockSubscription.getTelemetryObjects.andReturn(tmp); + updater.update(); + + // Should have 3 buffers for 3 objects + expect(updater.getBuffers().length).toEqual(3); + }); + + + it("shifts buffer upon expansion", function () { + // Count should be large enough to hit buffer's max size + var count = 1400, + i; + + // Initial update; should have 3 in first position + // (a's initial domain value) + updater.update(); + expect(updater.getBuffers()[0][1]).toEqual(123); + + // Simulate a lot of telemetry updates + for (i = 0; i < count; i += 1) { + testDomainValues.a += 1; + testRangeValues.a += 1; + updater.update(); + } + + // Value at front of the buffer should have been pushed out + expect(updater.getBuffers()[0][1]).not.toEqual(123); + }); }); } ); \ No newline at end of file