From 44fe2ec9ca5a8e5f2e29ebd12012404c169618aa Mon Sep 17 00:00:00 2001 From: Joel Fischer Date: Mon, 20 May 2019 15:19:49 -0400 Subject: Fix batching soft button manager updates --- SmartDeviceLink/SDLSoftButtonManager.m | 31 ++++++++++++-- SmartDeviceLink/SDLSoftButtonTransitionOperation.h | 2 +- .../DevAPISpecs/SDLSoftButtonManagerSpec.m | 48 ++++++++++++++++++++-- 3 files changed, 73 insertions(+), 8 deletions(-) diff --git a/SmartDeviceLink/SDLSoftButtonManager.m b/SmartDeviceLink/SDLSoftButtonManager.m index 3b00ba985..56deb83b0 100644 --- a/SmartDeviceLink/SDLSoftButtonManager.m +++ b/SmartDeviceLink/SDLSoftButtonManager.m @@ -46,6 +46,8 @@ NS_ASSUME_NONNULL_BEGIN @property (strong, nonatomic, nullable) SDLDisplayCapabilities *displayCapabilities; @property (strong, nonatomic, nullable) SDLSoftButtonCapabilities *softButtonCapabilities; +@property (strong, nonatomic) NSMutableArray *batchQueue; + @end @implementation SDLSoftButtonManager @@ -60,6 +62,7 @@ NS_ASSUME_NONNULL_BEGIN _currentLevel = nil; _transactionQueue = [self sdl_newTransactionQueue]; + _batchQueue = [NSMutableArray array]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_registerResponse:) name:SDLDidReceiveRegisterAppInterfaceResponse object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_displayLayoutResponse:) name:SDLDidReceiveSetDisplayLayoutResponse object:nil]; @@ -118,13 +121,30 @@ NS_ASSUME_NONNULL_BEGIN _softButtonObjects = softButtonObjects; SDLSoftButtonReplaceOperation *op = [[SDLSoftButtonReplaceOperation alloc] initWithConnectionManager:self.connectionManager fileManager:self.fileManager capabilities:self.softButtonCapabilities softButtonObjects:_softButtonObjects mainField1:self.currentMainField1]; - [self.transactionQueue cancelAllOperations]; - [self.transactionQueue addOperation:op]; + + if (self.isBatchingUpdates) { + [self.batchQueue removeAllObjects]; + [self.batchQueue addObject:op]; + } else { + [self.transactionQueue cancelAllOperations]; + [self.transactionQueue addOperation:op]; + } } - (void)sdl_transitionSoftButton:(SDLSoftButtonObject *)softButton { SDLSoftButtonTransitionOperation *op = [[SDLSoftButtonTransitionOperation alloc] initWithConnectionManager:self.connectionManager capabilities:self.softButtonCapabilities softButtons:self.softButtonObjects mainField1:self.currentMainField1]; - [self.transactionQueue addOperation:op]; + + if (self.isBatchingUpdates) { + for (SDLAsynchronousOperation *sbOperation in self.batchQueue) { + if ([sbOperation isMemberOfClass:[SDLSoftButtonTransitionOperation class]]) { + [self.batchQueue removeObject:sbOperation]; + } + } + + [self.batchQueue addObject:op]; + } else { + [self.transactionQueue addOperation:op]; + } } @@ -146,7 +166,10 @@ NS_ASSUME_NONNULL_BEGIN - (void)setBatchUpdates:(BOOL)batchUpdates { _batchUpdates = batchUpdates; - _transactionQueue.suspended = batchUpdates; + if (!_batchUpdates) { + [self.transactionQueue addOperations:[self.batchQueue copy] waitUntilFinished:NO]; + [self.batchQueue removeAllObjects]; + } } - (void)setCurrentMainField1:(nullable NSString *)currentMainField1 { diff --git a/SmartDeviceLink/SDLSoftButtonTransitionOperation.h b/SmartDeviceLink/SDLSoftButtonTransitionOperation.h index 86650dc3c..2679c9895 100644 --- a/SmartDeviceLink/SDLSoftButtonTransitionOperation.h +++ b/SmartDeviceLink/SDLSoftButtonTransitionOperation.h @@ -32,7 +32,7 @@ NS_ASSUME_NONNULL_BEGIN @param connectionManager The manager that will send the resultant RPCs @param capabilities The capabilites of the soft buttons on the current template - @param softButtonObjects The soft buttons that should be sent + @param softButtons The soft buttons that should be sent @param mainField1 The primary text field of the system template @return The transition operation */ diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLSoftButtonManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLSoftButtonManagerSpec.m index 772c8cbcd..3a7ac4a65 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLSoftButtonManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLSoftButtonManagerSpec.m @@ -12,7 +12,9 @@ #import "SDLSoftButtonCapabilities.h" #import "SDLSoftButtonManager.h" #import "SDLSoftButtonObject.h" +#import "SDLSoftButtonReplaceOperation.h" #import "SDLSoftButtonState.h" +#import "SDLSoftButtonTransitionOperation.h" #import "TestConnectionManager.h" @interface SDLSoftButtonObject() @@ -35,6 +37,8 @@ @property (strong, nonatomic, nullable) SDLDisplayCapabilities *displayCapabilities; @property (strong, nonatomic, nullable) SDLSoftButtonCapabilities *softButtonCapabilities; +@property (strong, nonatomic) NSMutableArray *batchQueue; + @end QuickSpecBegin(SDLSoftButtonManagerSpec) @@ -137,6 +141,21 @@ describe(@"a soft button manager", ^{ testManager.softButtonObjects = @[testObject1, testObject2]; }); + describe(@"while batching", ^{ + beforeEach(^{ + testManager.batchUpdates = YES; + + [testObject1 transitionToNextState]; + [testObject2 transitionToNextState]; + testManager.softButtonObjects = @[testObject2, testObject1]; + }); + + it(@"should properly queue the batching updates", ^{ + expect(testManager.transactionQueue.operationCount).to(equal(1)); + expect(testManager.batchQueue).to(haveCount(1)); + }); + }); + it(@"should set soft buttons correctly", ^{ expect(testManager.softButtonObjects).toNot(beNil()); expect(testObject1.buttonId).to(equal(0)); @@ -182,10 +201,33 @@ describe(@"a soft button manager", ^{ testManager.softButtonObjects = @[testObject1, testObject2]; }); - it(@"should queue an update", ^{ - [testObject1 transitionToStateNamed:object1State2Name]; + context(@"when batching", ^{ + beforeEach(^{ + testManager.batchUpdates = YES; + + SDLSoftButtonReplaceOperation *replaceOp = [[SDLSoftButtonReplaceOperation alloc] init]; + SDLSoftButtonTransitionOperation *transitionOp = [[SDLSoftButtonTransitionOperation alloc] init]; + testManager.batchQueue = [NSMutableArray arrayWithArray:@[replaceOp, transitionOp]]; + + [testObject1 transitionToStateNamed:object1State2Name]; + }); + + it(@"should batch queue the update and remove the old transition operation", ^{ + expect(testManager.transactionQueue.operationCount).to(equal(1)); + expect(testManager.batchQueue.count).to(equal(2)); + }); + }); + + context(@"when not batching", ^{ + beforeEach(^{ + testManager.batchUpdates = NO; + }); + + it(@"should queue an update", ^{ + [testObject1 transitionToStateNamed:object1State2Name]; - expect(testManager.transactionQueue.operationCount).to(equal(2)); // Replace and transition + expect(testManager.transactionQueue.operationCount).to(equal(2)); // Replace and transition + }); }); }); -- cgit v1.2.1