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 */ registernull15 internal func register(holder: ModuleHolder) { 16 log.info("Registering module '\(holder.name)'") 17 registry[holder.name] = holder 18 } 19 20 /** 21 Registers an instance of the module. 22 */ registernull23 public func register(module: AnyModule) { 24 guard let appContext else { 25 log.error("Unable to register a module '\(module)', the app context is unavailable") 26 return 27 } 28 register(holder: ModuleHolder(appContext: appContext, module: module)) 29 } 30 31 /** 32 Registers a module by its type. 33 */ registernull34 public func register(moduleType: AnyModule.Type) { 35 guard let appContext else { 36 log.error("Unable to register a module '\(moduleType)', the app context is unavailable") 37 return 38 } 39 register(module: moduleType.init(appContext: appContext)) 40 } 41 42 /** 43 Registers modules exported by given modules provider. 44 */ registernull45 public func register(fromProvider provider: ModulesProviderProtocol) { 46 provider.getModuleClasses().forEach { moduleType in 47 register(moduleType: moduleType) 48 } 49 } 50 51 /** 52 Unregisters given module from the registry. 53 */ unregisternull54 public func unregister(module: AnyModule) { 55 if let index = registry.firstIndex(where: { $1.module === module }) { 56 registry.remove(at: index) 57 } 58 } 59 unregisternull60 public func unregister(moduleName: String) { 61 if registry[moduleName] != nil { 62 log.info("Unregistering module '\(moduleName)'") 63 registry[moduleName] = nil 64 } 65 } 66 hasnull67 public func has(moduleWithName moduleName: String) -> Bool { 68 return registry[moduleName] != nil 69 } 70 getnull71 public func get(moduleHolderForName moduleName: String) -> ModuleHolder? { 72 return registry[moduleName] 73 } 74 getnull75 public func get(moduleWithName moduleName: String) -> AnyModule? { 76 return registry[moduleName]?.module 77 } 78 getModuleNamesnull79 public func getModuleNames() -> [String] { 80 return Array(registry.keys) 81 } 82 makeIteratornull83 public func makeIterator() -> IndexingIterator<[ModuleHolder]> { 84 return registry.map({ $1 }).makeIterator() 85 } 86 postnull87 internal func post(event: EventName) { 88 log.info("Posting '\(event)' event to registered modules") 89 forEach { holder in 90 holder.post(event: event) 91 } 92 } 93 post<PayloadType>null94 internal func post<PayloadType>(event: EventName, payload: PayloadType? = nil) { 95 log.info("Posting '\(event)' event to registered modules") 96 forEach { holder in 97 holder.post(event: event, payload: payload) 98 } 99 } 100 } 101