diff --git a/Limelight/Network/CleanupCrew.h b/Limelight/Network/CleanupCrew.h new file mode 100644 index 0000000..ae48f94 --- /dev/null +++ b/Limelight/Network/CleanupCrew.h @@ -0,0 +1,22 @@ +// +// CleanupCrew.h +// Limelight +// +// Created by Diego Waxemberg on 4/5/15. +// Copyright (c) 2015 Limelight Stream. All rights reserved. +// + +#import +#import "Host.h" + +@protocol CleanupCallback + +- (void) cleanedUpHosts:(NSSet*) host; + +@end + +@interface CleanupCrew : NSOperation + +- (id) initWithHostList:(NSArray*) hostList andCallback:(id)callback; + +@end diff --git a/Limelight/Network/CleanupCrew.m b/Limelight/Network/CleanupCrew.m new file mode 100644 index 0000000..791baf6 --- /dev/null +++ b/Limelight/Network/CleanupCrew.m @@ -0,0 +1,54 @@ +// +// CleanupCrew.m +// Limelight +// +// Created by Diego Waxemberg on 4/5/15. +// Copyright (c) 2015 Limelight Stream. All rights reserved. +// + +#import "CleanupCrew.h" + +@implementation CleanupCrew { + NSArray* _hostList; + id _callback; +} + +static const int CLEANUP_RATE = 2; + + +- (id) initWithHostList:(NSArray *)hostList andCallback:(id)callback { + self = [super init]; + _hostList = hostList; + _callback = callback; + return self; +} + +- (void) main { + while (!self.isCancelled) { + NSMutableSet* dirtyHosts = [[NSMutableSet alloc] init]; + + for (Host* host in _hostList) { + for (Host* other in _hostList) { + if (self.isCancelled) { + break; + } + + // We check the name as well as a hack to remove duplicates + if (host != other && ([host.uuid isEqualToString:other.uuid] + || [host.name isEqualToString:other.name])) { + [dirtyHosts addObject:other]; + } + } + } + + if (dirtyHosts.count > 0) { + [_callback cleanedUpHosts:dirtyHosts]; + } + + if (!self.cancelled) { + [NSThread sleepForTimeInterval:CLEANUP_RATE]; + } + } +} + +@end diff --git a/Limelight/Network/DiscoveryManager.h b/Limelight/Network/DiscoveryManager.h index f0a75a9..36db9ff 100644 --- a/Limelight/Network/DiscoveryManager.h +++ b/Limelight/Network/DiscoveryManager.h @@ -9,6 +9,7 @@ #import #import "MDNSManager.h" #import "Host.h" +#import "CleanupCrew.h" @protocol DiscoveryCallback @@ -16,7 +17,7 @@ @end -@interface DiscoveryManager : NSObject +@interface DiscoveryManager : NSObject - (id) initWithHosts:(NSArray*)hosts andCallback:(id) callback; - (void) startDiscovery; diff --git a/Limelight/Network/DiscoveryManager.m b/Limelight/Network/DiscoveryManager.m index 2478ff1..c08743e 100644 --- a/Limelight/Network/DiscoveryManager.m +++ b/Limelight/Network/DiscoveryManager.m @@ -15,7 +15,7 @@ #import "ServerInfoResponse.h" @implementation DiscoveryManager { - NSMutableArray* _hostQueue; + NSMutableArray* _hostList; NSMutableArray* _discoveredHosts; id _callback; MDNSManager* _mdnsMan; @@ -27,7 +27,7 @@ - (id)initWithHosts:(NSArray *)hosts andCallback:(id)callback { self = [super init]; - _hostQueue = [NSMutableArray arrayWithArray:hosts]; + _hostList = [NSMutableArray arrayWithArray:hosts]; _callback = callback; _opQueue = [[NSOperationQueue alloc] init]; _mdnsMan = [[MDNSManager alloc] initWithCallback:self]; @@ -66,9 +66,11 @@ Log(LOG_I, @"Starting discovery"); shouldDiscover = YES; [_mdnsMan searchForHosts]; - for (Host* host in _hostQueue) { + for (Host* host in _hostList) { [_opQueue addOperation:[self createWorkerForHost:host]]; } + CleanupCrew* cleanup = [[CleanupCrew alloc] initWithHostList:_hostList andCallback:self]; + [_opQueue addOperation:cleanup]; } - (void) stopDiscovery { @@ -88,8 +90,8 @@ } - (BOOL) addHostToDiscovery:(Host *)host { - if (![self isHostInDiscovery:host]) { - [_hostQueue addObject:host]; + if (host.uuid.length > 0 && ![self isHostInDiscovery:host]) { + [_hostList addObject:host]; if (shouldDiscover) { [_opQueue addOperation:[self createWorkerForHost:host]]; } @@ -104,7 +106,16 @@ [worker cancel]; } } - [_hostQueue removeObject:host]; + [_hostList removeObject:host]; +} + +// Override from CleanupCallback +- (void) cleanedUpHosts:(NSSet*)dirtyHosts { + for (Host* host in dirtyHosts) { + Log(LOG_I, @"Cleaning up duplicate host: %@", host.name); + [self removeHostFromDiscovery:host]; + } + [_callback updateAllHosts:_hostList]; } // Override from MDNSCallback @@ -119,7 +130,7 @@ [worker discoverHost]; if ([self addHostToDiscovery:host]) { Log(LOG_I, @"Adding host to discovery: %@", host.name); - [_callback updateAllHosts:_hostQueue]; + [_callback updateAllHosts:_hostList]; } else { Log(LOG_I, @"Not adding host to discovery: %@", host.name); [dataMan removeHost:host]; @@ -129,8 +140,8 @@ } - (BOOL) isHostInDiscovery:(Host*)host { - for (int i = 0; i < _hostQueue.count; i++) { - Host* discoveredHost = [_hostQueue objectAtIndex:i]; + for (int i = 0; i < _hostList.count; i++) { + Host* discoveredHost = [_hostList objectAtIndex:i]; if (discoveredHost.uuid.length > 0 && [discoveredHost.uuid isEqualToString:host.uuid]) { return YES; }