Chromium Code Reviews| Index: ios/chrome/app/deferred_initialization_runner.mm |
| diff --git a/ios/chrome/app/deferred_initialization_runner.mm b/ios/chrome/app/deferred_initialization_runner.mm |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..93dad0d7a04d46c3788a4adc3e476247c511dbf6 |
| --- /dev/null |
| +++ b/ios/chrome/app/deferred_initialization_runner.mm |
| @@ -0,0 +1,130 @@ |
| +// Copyright 2012 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/chrome/app/deferred_initialization_runner.h" |
| + |
| +#include "base/logging.h" |
| +#include "base/mac/scoped_nsobject.h" |
| + |
| +@interface DeferredInitializationRunner () |
| +// Returns the number of blocks that have been registered but not executed yet. |
| +- (NSUInteger)numberOfBlocksRemaining; |
|
sdefresne
2015/04/28 14:57:25
nit: this could be a readonly property
droger
2015/04/29 08:53:25
I removed the code, it's not used.
|
| +@end |
| + |
| +// An object encapsulating the deferred execution of a block of |
| +// initialization code. |
| +@interface DeferredInitializationBlock : NSObject { |
| + @private |
|
sdefresne
2015/04/28 14:57:25
nit: I think @private can be removed here since th
|
| + // A string to reference the initialization block. |
| + base::scoped_nsobject<NSString> name_; |
| + // A block of code to execute. |
| + base::scoped_nsprotocol<ProceduralBlock> runBlock_; |
| +} |
| + |
| +// Designated initializer. |
| +- (id)initWithName:(NSString*)name block:(ProceduralBlock)block; |
| + |
| +// Dispatches the deferred execution the block after |delaySeconds|. |
| +- (void)dispatch:(NSTimeInterval)delaySeconds; |
| + |
| +// Executes the deferred block now. |
| +- (void)runSynchronously; |
| + |
| +// Cancels the block's execution. |
| +- (void)cancel; |
| +@end |
| + |
| +@implementation DeferredInitializationBlock |
| + |
| +// Overrides default designated initializer. |
| +- (id)init { |
| + NOTREACHED(); |
| + return nil; |
| +} |
| + |
| +- (id)initWithName:(NSString*)name block:(ProceduralBlock)block { |
| + DCHECK(block); |
| + self = [super init]; |
| + if (self) { |
| + name_.reset([name copy]); |
| + runBlock_.reset([block copy]); |
| + } |
| + return self; |
| +} |
| + |
| +- (void)dispatch:(NSTimeInterval)delaySeconds { |
| + int64_t nanoseconds = delaySeconds * NSEC_PER_SEC; |
| + DCHECK([NSThread isMainThread]); |
| + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, nanoseconds), |
| + dispatch_get_main_queue(), ^() { |
| + [self runSynchronously]; |
| + }); |
| +} |
| + |
| +- (void)runSynchronously { |
| + ProceduralBlock deferredBlock = runBlock_.get(); |
| + if (!deferredBlock) |
| + return; |
| + deferredBlock(); |
| + [[DeferredInitializationRunner sharedInstance] cancelBlockNamed:name_]; |
| +} |
| + |
| +- (void)cancel { |
| + runBlock_.reset(); |
| +} |
| + |
| +@end |
| + |
| +@implementation DeferredInitializationRunner { |
| + @private |
|
sdefresne
2015/04/28 14:57:25
nit: idem, @private can be removed
|
| + base::scoped_nsobject<NSMutableDictionary> runBlocks_; |
| +} |
| + |
| ++ (DeferredInitializationRunner*)sharedInstance { |
| + static DeferredInitializationRunner* instance = |
| + [[DeferredInitializationRunner alloc] init]; |
| + return instance; |
| +} |
| + |
| +- (id)init { |
| + self = [super init]; |
| + if (self) |
| + runBlocks_.reset([[NSMutableDictionary dictionary] retain]); |
| + return self; |
| +} |
| + |
| +- (void)runBlockNamed:(NSString*)name |
| + after:(NSTimeInterval)delaySeconds |
| + block:(ProceduralBlock)block { |
| + DCHECK(name); |
| + // Safety check in case this function is called with a nanosecond or |
| + // microsecond parameter by mistake. |
| + DCHECK(delaySeconds < 3600.0); |
| + // Cancels the previously scheduled block, if there is one, so this |
| + // |name| block will not be run more than once. |
| + [[runBlocks_ objectForKey:name] cancel]; |
| + base::scoped_nsobject<DeferredInitializationBlock> deferredBlock( |
| + [[DeferredInitializationBlock alloc] initWithName:name block:block]); |
| + [runBlocks_ setObject:deferredBlock forKey:name]; |
| + [deferredBlock dispatch:delaySeconds]; |
| +} |
| + |
| +- (void)runBlockIfNecessary:(NSString*)name { |
| + [[runBlocks_ objectForKey:name] runSynchronously]; |
| +} |
| + |
| +- (void)cancelBlockNamed:(NSString*)name { |
| + DCHECK(name); |
| + [[runBlocks_ objectForKey:name] cancel]; |
| + [runBlocks_ removeObjectForKey:name]; |
| +} |
| + |
| +#pragma mark - |
| +#pragma mark Private Methods |
| + |
| +- (NSUInteger)numberOfBlocksRemaining { |
| + return [runBlocks_ count]; |
| +} |
| + |
| +@end |