What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal

Loading/Saving Settings Using the Styx.Helpers.Settings Class

Apoc

Well-Known Member
Joined
Jan 16, 2010
Messages
2,790
Reaction score
94
There have been a few people confused as to how they should save/load settings. Most tend to just include a Config.cs in their plugin or CC, however, what most people don't realize, is that saving it via XML is a far better idea, as you can have multiple different sets of settings, without having to keep multiple versions of the plugin/CC.

Honorbuddy provides you with 3 main things to make your life as a developer, much easier.

  • Styx.Helpers.Settings - A small class to handle loading/saving XML based on 'itself' (more explanation later)
  • Styx.Helpers.SettingAttribute - An attribute to define a property as a setting to be saved as XML
  • Styx.Helpers.DefaultValueAttribute - An attribute to define a setting's default value (optional)

Lets first talk about the main Styx.Helpers.Settings class.

By itself, it's mostly... well.. worthless. It can only load or save XML from a class that it is a parent of. You can think of it as a serializer, that works a lot better than .NET's tools.

Here's a quick example of how to create a class that can load and save XML.

Code:
using System.IO;

using Styx.Helpers;

namespace SettingsExample
{
    public class MySettings : Settings
    {
        public MySettings(string settingsPath) : base(settingsPath)
        {
            // Simply load the settings.
            Load();
        }

        public MySettings()
            : this(Path.Combine(Logging.ApplicationPath, "MySettings.xml"))
        {

        }
    }
}

As you'll notice, I included 2 different constructor variations. The first, allows you to define the filepath for the settings, wherever you please. The 2nd, will save the settings in the root HB directory, as MySettings.xml.

Keep in mind; since it is a child class of Settings, you have access to the public functions/properties/etc of the Settings class. You'll need to call Save() at some point, or the settings won't actually be persisted!

Now that you know how to define your settings class, lets get into how to actually add some settings.

The Settings class provided by Honorbuddy allows you to use quite a few datatypes in your properties. (Yes, properties. Explained below) All the basic datatypes are supported (int, uint, ulong, string, byte, float, etc), as well as arrays of said datatypes (int[], string[], byte[], etc). It also supports enums, for example, the ShapeshiftForm enum, etc. (Note: enums are saved as 'plain text' values, so using flags isn't recommended, or tested. They are saved as if you called myEnumValue.ToString())

NOTE: Generic collections (or collections other than arrays) ARE NOT SUPPORTED. List<T>, Dictionaries, Hashtables, etc, will not be saved or loaded. (You'll likely see an exception, or crash)

With that said, how about we add a few basic settings to our MySettings class.

Code:
using System.IO;

using Styx.Helpers;

namespace SettingsExample
{
    public class MySettings : Settings
    {
        public MySettings(string settingsPath) : base(settingsPath)
        {
            // Simply load the settings.
            Load();
        }

        public MySettings()
            : this(Path.Combine(Logging.ApplicationPath, "MySettings.xml"))
        {
        }

        [Setting, DefaultValue(80)]
        public int RestHealth { get; set; }

        [Setting, DefaultValue("Awesome Spell")]
        public string MainCastSpell { get; set; }

        [Setting, DefaultValue(true)]
        public bool UseMainCastSpell { get; set; }

        [Setting]
        public int[] RandomSpellIds { get; set; }
    }
}

As you can see, it looks like your normal definition of a settings class. A bunch of properties corresponding to some value. Note however, that all the settings are properties, and not fields, or methods. (You will get compiler errors trying to put a SettingAttribute on a non-property)

Also notice, I have not 'initialized' any of them. The base class handles all the logic!

Some of the settings also have a DefaultValueAttribute on them as well, this allows you to... well... give them default values! If a property doesn't have a DefaultValueAttribute on it, it will simply be the .NET default value. (In the case of RandomSpellIds, this would be null)

When the XML is saved, it will (by default) save each setting as an XML element, using the name of the property for the name of the element, and the value of the property, for the value of the element. Datatypes are determined at runtime, so no typical .NET serialization techniques are used to determine the datatype. (Such as adorning an element with a string: namespace, etc)

The SettingAttribute also has some extra parameters that you can set, if you want to make life easier for users who prefer to set the stuff in the XML, or you just want to use custom XML elements. The following is an example of some settings using those parameters:

Code:
        [Setting(Explanation = "This setting has some random reason for being here. This explanation doesn't help a user, but it explains what it does!")]
        public int ReallyRandomSetting { get; set; }

        [Setting(ElementName = "MyAwesomeSetting")]
        public bool MyNotReallyAwesomeSetting { get; set; }

        [Setting("AmbiguousSetting", "This setting is definitely easy to tell what it does!")]
        public int ObscureSetting { get; set; }

The Explanation is pretty straightforward. It will add an XML comment above the setting, with the text defined.

The ElementName is also straightforward. It allows you to override the XML element name used when saving/loading the setting.

I also included an example of using the attribute's constructor for brevity.


Why should you use the Styx.Helpers.Settings class, over the built-in Settings stuff for WinForms?

The stuff built into .NET for WinForms settings, only saves settings on a per-directory basis. So if a user moves HB to a new directory, you'll more than likely lose all your saved settings (As they no longer correspond to the same settings file). Using the Settings class that we provide, will work no matter where the user moves the bot to. So long as the file isn't deleted/renamed or otherwise can't be found, it will be able to load the settings without issue.

How you use this information is entirely up to you. This is simply a very quick explanation on how it works!
 
Is there any way to save multiple values in a setting? I've made a struct holding 2 strings and want to save all those objects in a setting.
 
Back
Top