// Adds any missing platforms: // * From the template collection // * From the legacy settings public void AddMissingPlatforms() { var newPlatforms = new List <Platform>(); foreach (Settings.PlatformTemplate template in Settings.PlatformTemplates) { if (!RuntimeSettings.PlatformExists(template.Identifier)) { newPlatforms.Add(template.CreateInstance()); } } // Ensure that the default platform exists if (!RuntimeSettings.DefaultPlatform) { RuntimeSettings.DefaultPlatform = ScriptableObject.CreateInstance <PlatformDefault>(); newPlatforms.Add(RuntimeSettings.DefaultPlatform); } // Ensure that the Play In Editor platform exists if (!RuntimeSettings.PlayInEditorPlatform) { RuntimeSettings.PlayInEditorPlatform = ScriptableObject.CreateInstance <PlatformPlayInEditor>(); newPlatforms.Add(RuntimeSettings.PlayInEditorPlatform); } // Ensure that the default and Play In Editor platforms have properties AffirmPlatformProperties(RuntimeSettings.DefaultPlatform); AffirmPlatformProperties(RuntimeSettings.PlayInEditorPlatform); // Migrate plugins if necessary var PluginsProperty = Platform.PropertyAccessors.Plugins; if (!RuntimeSettings.MigratedPlatforms.Contains(RuntimeSettings.DefaultPlatform.LegacyIdentifier)) { PluginsProperty.Set(RuntimeSettings.DefaultPlatform, RuntimeSettings.Plugins); } else if (!PluginsProperty.HasValue(RuntimeSettings.DefaultPlatform)) { PluginsProperty.Set(RuntimeSettings.DefaultPlatform, new List <string>()); } // Migrate LiveUpdatePort if (!Platform.PropertyAccessors.LiveUpdatePort.HasValue(RuntimeSettings.DefaultPlatform)) { Platform.PropertyAccessors.LiveUpdatePort.Set(RuntimeSettings.DefaultPlatform, RuntimeSettings.LiveUpdatePort); } // Create a map for migrating legacy settings var platformMap = new Dictionary <Legacy.Platform, Platform>(); foreach (Platform platform in RuntimeSettings.Platforms.Concat(newPlatforms)) { if (platform.LegacyIdentifier != Legacy.Platform.None) { platformMap.Add(platform.LegacyIdentifier, platform); } } Func <Legacy.Platform, Platform> AffirmPlatform = null; // Ensures that all of the platform's ancestors exist. Action <Platform> AffirmAncestors = (platform) => { Legacy.Platform legacyParent = Legacy.Parent(platform.LegacyIdentifier); if (legacyParent != Legacy.Platform.None) { platform.ParentIdentifier = AffirmPlatform(legacyParent).Identifier; } }; // Gets the platform corresponding to legacyPlatform (or creates it if it is a group), // and ensures that it has properties and all of its ancestors exist. // Returns null if legacyPlatform is unknown. AffirmPlatform = (legacyPlatform) => { Platform platform; if (platformMap.TryGetValue(legacyPlatform, out platform)) { platform.AffirmProperties(); } else if (Legacy.IsGroup(legacyPlatform)) { PlatformGroup group = PlatformGroup.Create(Legacy.DisplayName(legacyPlatform), legacyPlatform); platformMap.Add(legacyPlatform, group); newPlatforms.Add(group); platform = group; } else { // This is an unknown platform return(null); } AffirmAncestors(platform); return(platform); }; // Gets the target plaform to use when migrating settings from legacyPlatform. // Returns null if legacyPlatform is unknown or has already been migrated. Func <Legacy.Platform, Platform> getMigrationTarget = (legacyPlatform) => { if (RuntimeSettings.MigratedPlatforms.Contains(legacyPlatform)) { // Already migrated return(null); } return(AffirmPlatform(legacyPlatform)); }; var speakerModeSettings = RuntimeSettings.SpeakerModeSettings.ConvertAll( setting => new Legacy.PlatformSetting <FMOD.SPEAKERMODE>() { Value = (FMOD.SPEAKERMODE)setting.Value, Platform = setting.Platform } ); // Migrate all the legacy settings, creating platforms as we need them via AffirmPlatform MigrateLegacyPlatforms(speakerModeSettings, Platform.PropertyAccessors.SpeakerMode, getMigrationTarget); MigrateLegacyPlatforms(RuntimeSettings.SampleRateSettings, Platform.PropertyAccessors.SampleRate, getMigrationTarget); MigrateLegacyPlatforms(RuntimeSettings.LiveUpdateSettings, Platform.PropertyAccessors.LiveUpdate, getMigrationTarget); MigrateLegacyPlatforms(RuntimeSettings.OverlaySettings, Platform.PropertyAccessors.Overlay, getMigrationTarget); MigrateLegacyPlatforms(RuntimeSettings.BankDirectorySettings, Platform.PropertyAccessors.BuildDirectory, getMigrationTarget); MigrateLegacyPlatforms(RuntimeSettings.VirtualChannelSettings, Platform.PropertyAccessors.VirtualChannelCount, getMigrationTarget); MigrateLegacyPlatforms(RuntimeSettings.RealChannelSettings, Platform.PropertyAccessors.RealChannelCount, getMigrationTarget); // Now we ensure that if a legacy group has settings, all of its descendants exist // and inherit from it (even if they have no settings of their own), so that the // inheritance structure matches the old system. // We look at all groups (not just newly created ones), because a newly created platform // may need to inherit from a preexisting group. var groupsToProcess = new Queue <Platform>(platformMap.Values.Where( platform => platform is PlatformGroup && platform.LegacyIdentifier != Legacy.Platform.None && platform.HasAnyOverriddenProperties)); while (groupsToProcess.Count > 0) { Platform group = groupsToProcess.Dequeue(); // Ensure that all descendants exist foreach (var child in platformMap.Values) { if (child.Active) { // Don't overwrite existing settings continue; } var legacyPlatform = child.LegacyIdentifier; if (legacyPlatform == Legacy.Platform.iOS || legacyPlatform == Legacy.Platform.Android) { // These platforms were overridden by MobileHigh and MobileLow in the old system continue; } if (RuntimeSettings.MigratedPlatforms.Contains(legacyPlatform)) { // The user may have deleted this platform since migration, so don't mess with it continue; } if (Legacy.Parent(legacyPlatform) == group.LegacyIdentifier) { child.AffirmProperties(); child.ParentIdentifier = group.Identifier; if (child is PlatformGroup) { groupsToProcess.Enqueue(child as PlatformGroup); } } } } // Add all of the new platforms to the set of known platforms foreach (Platform platform in newPlatforms) { RuntimeSettings.AddPlatform(platform); } RuntimeSettings.ForEachPlatform(UpdateMigratedPlatform); }