public Module(ModuleConfig config) { m_eventManager = config.GetEventManager(); m_dependencies = config.GetDependencies(); m_sName = config.GetName(); m_iUid = config.GetUid(); m_iModuleAvailableEventUid = config.GetEngineEvents(). GetEventTypeUid(EngineEvents.Types.MODULE_AVAILABLE); m_iModuleUnavailableEventUid = config.GetEngineEvents(). GetEventTypeUid(EngineEvents.Types.MODULE_UNAVAILABLE); m_iDependencyRequestEventUid = config.GetEngineEvents(). GetEventTypeUid(EngineEvents.Types.DEPENDENCY_REQUEST); m_eventManager.AddEventListener(this, m_iModuleAvailableEventUid); m_eventManager.AddEventListener(this, m_iModuleUnavailableEventUid); foreach (string sDependencyName in config.GetDependencies()) { m_eventManager.LaunchEvent(m_iDependencyRequestEventUid, sDependencyName); } }
/// <summary> /// Adds a module of the given type. Modules must have unique names. Modules must provide a public /// constructor that takes a ModuleConfig and at most one other parameter whose type must be specified /// as the second type parameter to this function. /// </summary> /// <typeparam name="ModuleType">The type of module to create. Must inherit from Framework.Module</typeparam> /// <typeparam name="ConfigType">The type of configuration object to forward to the module constructor</typeparam> /// <param name="sName">The name by which to refer to the module</param> /// <param name="dependencies">A list of module names that this module requires access to</param> /// <returns>True if the module was successfully added, false otherwise</returns> /// <exception cref="ModuleException">Thrown when no valid module constructor could be found</throws> public bool AddModule <ModuleType, ConfigType>(ConfigType config, string sName, List <string> dependencies) where ModuleType : Module { if (string.IsNullOrEmpty(sName)) { return(false); } // Dont allow modules to specify themselves as dependencies. Also filter out duplicates and // invalid values. if (dependencies == null) { dependencies = new List <string>(); } dependencies.Remove(sName); SortedSet <string> dependencyFilter = new SortedSet <string>(); foreach (string sDependencyName in dependencies) { if (!string.IsNullOrWhiteSpace(sDependencyName)) { dependencyFilter.Add(sDependencyName); } } dependencies = new List <string>(); foreach (string sDependencyName in dependencyFilter) { dependencies.Add(sDependencyName); } // Module names must be unique foreach (Module m in m_modules) { if (m.GetName() == sName) { return(false); } } ModuleConfig moduleConfig = new ModuleConfig(m_iNextModuleUid++, sName, m_eventManager, m_engineEvents, dependencies); ModuleType module = null; // Locate a constructor with the correct parameters. The first viable constructor will be used. Valid // formats are: // 1) ConfigType, ModuleConfig // 2) ModuleConfig, ConfigType // 3) ModuleConfig ConstructorInfo[] constructors = typeof(ModuleType).GetConstructors(); foreach (ConstructorInfo constructor in constructors) { ParameterInfo[] parameters = constructor.GetParameters(); if (parameters.Length == 1) { if (parameters[0].ParameterType == typeof(ModuleConfig)) { module = (ModuleType)Activator.CreateInstance(typeof(ModuleType), moduleConfig); break; } } else if (parameters.Length == 2) { if (parameters[0].ParameterType == typeof(ModuleConfig) && parameters[1].ParameterType == typeof(ConfigType)) { module = (ModuleType)Activator.CreateInstance(typeof(ModuleType), moduleConfig, config); break; } else if (parameters[0].ParameterType == typeof(ConfigType) && parameters[1].ParameterType == typeof(ModuleConfig)) { module = (ModuleType)Activator.CreateInstance(typeof(ModuleType), config, moduleConfig); break; } } else { continue; } } if (module == null) { throw new ModuleException("Failed to construct module of type " + typeof(ModuleType).Name + " with name '" + sName + "'. A constructor accepting one of the following is required: " + "(ModuleConfig), (ModuleConfig, CustomParameter) or (CustomParameter, ModuleConfig)."); } m_modules.Add(module); m_eventManager.LaunchEvent(m_iModuleAvailableEventUid, module); return(true); }