/// <summary> /// Disables the current module and changes it to the provided module. /// </summary> /// <param name="moduleModel">The module to activate</param> /// <param name="loopManager">Optionally pass the LoopManager to automatically start it, if it's not running.</param> /// <param name="storeAsLast">Whether or not to store this effect as the last effect</param> public void ChangeActiveModule(ModuleModel moduleModel, LoopManager loopManager = null, bool storeAsLast = true) { if (_waitEffect != null) { _logger.Debug("Stopping module change because a change is already queued"); return; } if (moduleModel == null) { throw new ArgumentNullException(nameof(moduleModel)); } if (_deviceManager.ActiveKeyboard == null) { _logger.Debug("Stopping module change until keyboard is enabled"); _waitEffect = moduleModel; _waitLoopManager = loopManager; _deviceManager.OnKeyboardChanged += DeviceManagerOnOnKeyboardChanged; _deviceManager.EnableLastKeyboard(); return; } // Process bound modules are only used if they are enabled if (moduleModel.Settings != null && !moduleModel.Settings.IsEnabled && moduleModel.IsBoundToProcess) { _logger.Debug("Cancelling module change, provided module is process bound and not enabled"); return; } var wasNull = false; if (ActiveModule == null) { wasNull = true; ActiveModule = moduleModel; } lock (ActiveModule) { if (!wasNull) { ActiveModule.Dispose(); } lock (moduleModel) { ActiveModule = moduleModel; ActiveModule.Enable(); if (!ActiveModule.IsInitialized) { _logger.Debug("Cancelling module change, couldn't initialize the module ({0})", moduleModel.Name); ActiveModule = null; return; } } } if (loopManager != null && !loopManager.Running) { _logger.Debug("Starting LoopManager for module change"); loopManager.StartAsync(); } if (!ActiveModule.IsBoundToProcess && !ActiveModule.IsOverlay && storeAsLast) { _generalSettings.LastModule = ActiveModule?.Name; _generalSettings.Save(); } _logger.Debug("Changed active module to: {0}", moduleModel.Name); RaiseEffectChangedEvent(new ModuleChangedEventArgs(moduleModel)); }