예제 #1
0
        /// <summary>
        ///     Deep-clones the setting group.
        /// </summary>
        /// <returns>The new group.</returns>
        public SettingsGroup DeepClone()
        {
            var result = new SettingsGroup();

            foreach (var setting in _settings)
            {
                result._settings[setting.Key] = setting.Value;
            }
            foreach (var group in _groups)
            {
                result._groups[group.Key] = group.Value.DeepClone();
            }
            return(result);
        }
예제 #2
0
        /// <summary>
        ///     Gets the value of a setting by path.
        /// </summary>
        /// <typeparam name="T">The type of the setting.</typeparam>
        /// <param name="path">The path of the value to get.</param>
        /// <param name="getter">A function that gets the value once the bottom-level group is found.</param>
        /// <returns>The value of the setting, as returned by the getter.</returns>
        private T GetSettingByPath <T>(string path, Func <SettingsGroup, string, T> getter)
        {
            string[]      pathComponents = SplitPath(path);
            SettingsGroup currentGroup   = this;

            for (int i = 0; i < pathComponents.Length; i++)
            {
                string component = pathComponents[i];
                if (i == pathComponents.Length - 1)
                {
                    return(getter(currentGroup, component));
                }
                currentGroup = currentGroup._groups[component];
            }
            throw new ArgumentException("Invalid path");
        }
예제 #3
0
        /// <summary>
        ///     Loads a settings group from an XML container.
        /// </summary>
        /// <param name="container">The container to read settings from.</param>
        /// <returns>The loaded settings group.</returns>
        public SettingsGroup LoadSettingsGroup(XContainer container)
        {
            var result = new SettingsGroup();

            foreach (XElement elem in container.Elements())
            {
                if (elem.HasElements)
                {
                    result.SetGroup(elem.Name.LocalName, LoadSettingsGroup(elem));
                }
                else
                {
                    result.SetSetting(elem.Name.LocalName, LoadSetting(elem));
                }
            }
            return(result);
        }
예제 #4
0
        /// <summary>
        ///     Determines whether or not a given path has a value defined for it.
        /// </summary>
        /// <param name="path">The path to check.</param>
        /// <returns><c>true</c> if the path has a value defined.</returns>
        public bool PathExists(string path)
        {
            string[]      pathComponents = SplitPath(path);
            SettingsGroup currentGroup   = this;

            for (int i = 0; i < pathComponents.Length; i++)
            {
                string component = pathComponents[i];
                if (i == pathComponents.Length - 1)
                {
                    return(currentGroup._settings.ContainsKey(component) ||
                           currentGroup._groups.ContainsKey(component));
                }
                if (!currentGroup._groups.TryGetValue(component, out currentGroup))
                {
                    return(false);
                }
            }
            return(false);
        }
예제 #5
0
        /// <summary>
        ///     Imports settings recursively from another group.
        ///     Any existing settings will be overwritten, and all sub-groups will be merged.
        /// </summary>
        /// <param name="other">The group to import from.</param>
        public void Import(SettingsGroup other)
        {
            foreach (var setting in other._settings)
            {
                _settings[setting.Key] = setting.Value;
            }

            foreach (var group in other._groups)
            {
                SettingsGroup existingGroup;
                if (_groups.TryGetValue(group.Key, out existingGroup))
                {
                    existingGroup.Import(group.Value);
                }
                else
                {
                    _groups[group.Key] = group.Value;
                }
            }
        }
예제 #6
0
        /// <summary>
        ///     Sets the value of a setting by path. Any groups will be created along the way.
        /// </summary>
        /// <param name="path">The path to the setting.</param>
        /// <param name="setter">An action that sets the value once the bottom-level group is found.</param>
        private void SetSettingByPath(string path, Action <SettingsGroup, string> setter)
        {
            string[]      pathComponents = SplitPath(path);
            SettingsGroup currentGroup   = this;

            for (int i = 0; i < pathComponents.Length; i++)
            {
                string component = pathComponents[i];
                if (i == pathComponents.Length - 1)
                {
                    setter(currentGroup, component);
                    return;
                }
                if (!currentGroup._groups.TryGetValue(component, out currentGroup))
                {
                    // Sub-group does not exist - create one
                    var newGroup = new SettingsGroup();
                    currentGroup._groups[component] = newGroup;
                    currentGroup = newGroup;
                }
            }
        }
예제 #7
0
        /// <summary>
        ///     Loads an engine database from an XML container.
        /// </summary>
        /// <param name="container">The container to read engine elements from.</param>
        /// <returns>The built engine database.</returns>
        public static EngineDatabase LoadDatabase(XContainer container)
        {
            XMLSettingsGroupLoader loader = CreateSettingsGroupLoader();
            var result = new EngineDatabase();

            foreach (XElement elem in container.Elements("engine"))
            {
                string        name     = XMLUtil.GetStringAttribute(elem, "name");
                string        version  = XMLUtil.GetStringAttribute(elem, "version");
                string        inherits = XMLUtil.GetStringAttribute(elem, "inherits", null);
                SettingsGroup settings = loader.LoadSettingsGroup(elem);
                if (!string.IsNullOrWhiteSpace(inherits))
                {
                    // Clone the base engine's settings and then import the new settings on top of it
                    SettingsGroup baseSettings = result.FindEngineByName(inherits).Settings.DeepClone();
                    baseSettings.Import(settings);
                    settings = baseSettings;
                }
                var desc = new EngineDescription(name, version, settings);
                result.RegisterEngine(desc);
            }
            return(result);
        }
예제 #8
0
 /// <summary>
 ///     Sets a sub-group.
 /// </summary>
 /// <param name="path">The path to the sub-group to set.</param>
 /// <param name="newGroup">The value of the group.</param>
 public void SetGroup(string path, SettingsGroup newGroup)
 {
     SetSettingByPath(path, (group, name) => group._groups[name] = newGroup);
 }