blob: 0d88d88ba2826e709589fc4efa0257c0312eee47 [file] [log] [blame]
// Copyright 2013 The Flutter 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 "FWFInstanceManager.h"
@interface FWFInstanceManager ()
@property dispatch_queue_t lockQueue;
@property NSMapTable<NSNumber *, NSObject *> *identifiersToInstances;
@property NSMapTable<NSObject *, NSNumber *> *instancesToIdentifiers;
@end
@implementation FWFInstanceManager
- (instancetype)init {
if (self) {
self.lockQueue = dispatch_queue_create("FWFInstanceManager", DISPATCH_QUEUE_SERIAL);
self.identifiersToInstances = [NSMapTable strongToStrongObjectsMapTable];
self.instancesToIdentifiers = [NSMapTable strongToStrongObjectsMapTable];
}
return self;
}
- (void)addInstance:(nonnull NSObject *)instance withIdentifier:(long)instanceIdentifier {
NSAssert(instance && instanceIdentifier >= 0,
@"Instance must be nonnull and identifier must be >= 0.");
dispatch_async(_lockQueue, ^{
[self.instancesToIdentifiers setObject:@(instanceIdentifier) forKey:instance];
[self.identifiersToInstances setObject:instance forKey:@(instanceIdentifier)];
});
}
- (nullable NSObject *)removeInstanceWithIdentifier:(long)instanceIdentifier {
NSObject *__block instance = nil;
dispatch_sync(_lockQueue, ^{
instance = [self.identifiersToInstances objectForKey:@(instanceIdentifier)];
if (instance) {
[self.identifiersToInstances removeObjectForKey:@(instanceIdentifier)];
[self.instancesToIdentifiers removeObjectForKey:instance];
}
});
return instance;
}
- (long)removeInstance:(NSObject *)instance {
NSAssert(instance, @"Instance must be nonnull.");
NSNumber *__block identifierNumber = nil;
dispatch_sync(_lockQueue, ^{
identifierNumber = [self.instancesToIdentifiers objectForKey:instance];
if (identifierNumber) {
[self.identifiersToInstances removeObjectForKey:identifierNumber];
[self.instancesToIdentifiers removeObjectForKey:instance];
}
});
return identifierNumber ? identifierNumber.longValue : NSNotFound;
}
- (nullable NSObject *)instanceForIdentifier:(long)instanceIdentifier {
NSObject *__block instance = nil;
dispatch_sync(_lockQueue, ^{
instance = [self.identifiersToInstances objectForKey:@(instanceIdentifier)];
});
return instance;
}
- (long)identifierForInstance:(nonnull NSObject *)instance {
NSNumber *__block identifierNumber = nil;
dispatch_sync(_lockQueue, ^{
identifierNumber = [self.instancesToIdentifiers objectForKey:instance];
});
return identifierNumber ? identifierNumber.longValue : NSNotFound;
}
@end