Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(273)

Unified Diff: ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.mm

Issue 2680403005: Introduce WebStateList to manage a list of web::WebState. (Closed)
Patch Set: Rebase. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.mm
diff --git a/ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.mm b/ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.mm
new file mode 100644
index 0000000000000000000000000000000000000000..e1fd571c23e51be1959e9064e068d3b0571d38b2
--- /dev/null
+++ b/ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.mm
@@ -0,0 +1,147 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#import "ios/shared/chrome/browser/tabs/web_state_list.h"
+#import "ios/shared/chrome/browser/tabs/web_state_list_observer_bridge.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+#pragma mark - WebStateListFastEnumerationHelperObserver
+
+// Observer for WebStateListFastEnumerationHelper that will increment the
+// mutation counter provided in the constructor every time the WebStateList
+// it is tracking is modified.
+@interface WebStateListFastEnumerationHelperObserver
+ : NSObject<WebStateListObserving>
+
+// Initializes the observer with a pointer to the mutation counter to increment
+// when the WebStateList is mutated.
+- (instancetype)initWithMutationCounter:(unsigned long*)mutationCounter
+ NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)init NS_UNAVAILABLE;
+
+@end
+
+@implementation WebStateListFastEnumerationHelperObserver {
+ // Pointer to the mutation counter to increment when the WebStateList is
+ // mutated.
+ unsigned long* _mutationCounter;
+}
+
+- (instancetype)initWithMutationCounter:(unsigned long*)mutationCounter {
+ DCHECK(mutationCounter);
+ if ((self = [super init]))
+ _mutationCounter = mutationCounter;
+ return self;
+}
+
+#pragma mark WebStateListObserving
+
+- (void)webStateList:(WebStateList*)webStateList
+ didInsertWebState:(web::WebState*)webState
+ atIndex:(int)index {
+ ++*_mutationCounter;
+}
+
+- (void)webStateList:(WebStateList*)webStateList
+ didMoveWebState:(web::WebState*)webState
+ fromIndex:(int)fromIndex
+ toIndex:(int)toIndex {
+ ++*_mutationCounter;
+}
+
+- (void)webStateList:(WebStateList*)webStateList
+ didReplaceWebState:(web::WebState*)oldWebState
+ byWebState:(web::WebState*)newWebState
+ atIndex:(int)index {
+ ++*_mutationCounter;
+}
+
+- (void)webStateList:(WebStateList*)webStateList
+ didDetachWebState:(web::WebState*)webState
+ atIndex:(int)index {
+ ++*_mutationCounter;
+}
+
+@end
+
+#pragma mark - WebStateListFastEnumerationHelper
+
+@implementation WebStateListFastEnumerationHelper {
+ // The wrapped WebStateList.
+ WebStateList* _webStateList;
+
+ // Helper that returns Objective-C proxies for WebState objects.
+ id<WebStateProxyFactory> _proxyFactory;
+
+ // WebStateListObserverBridge forwarding the events of WebStateList to self.
+ std::unique_ptr<WebStateListObserverBridge> _observerBridge;
+
+ // Counter incremented each time the WebStateList is mutated.
+ unsigned long _mutationCounter;
+}
+
+- (instancetype)initWithWebStateList:(WebStateList*)webStateList
+ proxyFactory:(id<WebStateProxyFactory>)proxyFactory {
+ DCHECK(webStateList);
+ DCHECK(proxyFactory);
+ if ((self = [super init])) {
+ _webStateList = webStateList;
+ _proxyFactory = proxyFactory;
+ _observerBridge = base::MakeUnique<WebStateListObserverBridge>(
+ [[WebStateListFastEnumerationHelperObserver alloc]
+ initWithMutationCounter:&_mutationCounter]);
+ _webStateList->AddObserver(_observerBridge.get());
+ }
+ return self;
+}
+
+- (void)dealloc {
+ _webStateList->RemoveObserver(_observerBridge.get());
+}
+
+#pragma mark NSFastEnumeration
+
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state
+ objects:(id __unsafe_unretained*)buffer
+ count:(NSUInteger)len {
+ // The number of objects already returned is stored in |state->state|. For
+ // the first iteration, the counter will be zero and the rest of the state
+ // structure need to be initialised.
+ DCHECK_LE(state->state, static_cast<unsigned long>(INT_MAX));
+ const int offset = state->state;
+ if (offset == 0)
+ state->mutationsPtr = &_mutationCounter;
+
+ if (len > static_cast<unsigned long>(INT_MAX))
+ len = static_cast<unsigned long>(INT_MAX);
+
+ DCHECK_LE(offset, _webStateList->count());
+ const int count =
+ std::min(static_cast<int>(len), _webStateList->count() - offset);
+
+ for (int index = 0; index < count; ++index) {
+ web::WebState* webState = _webStateList->GetWebStateAt(offset + index);
+ __autoreleasing id wrapper = [_proxyFactory proxyForWebState:webState];
+ buffer[index] = wrapper;
+ }
+
+ state->state += count;
+ state->itemsPtr = buffer;
+
+ return static_cast<NSUInteger>(count);
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698