1 public final class ModuleRegistry: Sequence { 2 public typealias Element = ModuleHolder 3 4 private weak var appContext: AppContext? 5 6 private var registry: [String: ModuleHolder] = [:] 7 8 init(appContext: AppContext) { 9 self.appContext = appContext 10 } 11 12 /** 13 Registers an instance of module holder. 14 */ 15 internal func register(holder: ModuleHolder) { 16 log.info("Registering module '\(holder.name)'") 17 registry[holder.name] = holder 18 } 19 20 /** 21 Registers a module by its type. 22 */ 23 public func register(moduleType: AnyModule.Type) { 24 guard let appContext = appContext else { 25 return 26 } 27 let module = moduleType.init(appContext: appContext) 28 let holder = ModuleHolder(appContext: appContext, module: module) 29 register(holder: holder) 30 } 31 32 /** 33 Registers modules exported by given modules provider. 34 */ 35 public func register(fromProvider provider: ModulesProviderProtocol) { 36 provider.getModuleClasses().forEach { moduleType in 37 register(moduleType: moduleType) 38 } 39 } 40 41 /** 42 Unregisters given module from the registry. 43 */ 44 public func unregister(module: AnyModule) { 45 if let index = registry.firstIndex(where: { $1.module === module }) { 46 registry.remove(at: index) 47 } 48 } 49 50 public func unregister(moduleName: String) { 51 if registry[moduleName] != nil { 52 log.info("Unregistering module '\(moduleName)'") 53 registry[moduleName] = nil 54 } 55 } 56 57 public func has(moduleWithName moduleName: String) -> Bool { 58 return registry[moduleName] != nil 59 } 60 61 public func get(moduleHolderForName moduleName: String) -> ModuleHolder? { 62 return registry[moduleName] 63 } 64 65 public func get(moduleWithName moduleName: String) -> AnyModule? { 66 return registry[moduleName]?.module 67 } 68 69 public func getModuleNames() -> [String] { 70 return Array(registry.keys) 71 } 72 73 public func makeIterator() -> IndexingIterator<[ModuleHolder]> { 74 return registry.map({ $1 }).makeIterator() 75 } 76 77 internal func post(event: EventName) { 78 log.info("Posting '\(event)' event to registered modules") 79 forEach { holder in 80 holder.post(event: event) 81 } 82 } 83 84 internal func post<PayloadType>(event: EventName, payload: PayloadType? = nil) { 85 log.info("Posting '\(event)' event to registered modules") 86 forEach { holder in 87 holder.post(event: event, payload: payload) 88 } 89 } 90 } 91