[bug] Private fields for custom types cannot be written

Discussion and help for Easy Save 3
Post Reply
Gladyon
Posts: 30
Joined: Thu Sep 07, 2017 6:51 am

[bug] Private fields for custom types cannot be written

Post by Gladyon »

I have a custom type, which contains a private field.
When I use the 'Easy Save Types' window to create an ES3Type, the generated type is incorrect:

Here is the custom type:
/// <summary>
/// Manage a profile
/// </summary>
[Serializable]  // Needed for ES3 serialization (and also, the fields must NOT begin with 'm_', or they won't be serialized)
public class QProfile
{
    /// <summary>The name of the profile</summary>
    public String Name { get { return _Name; } }
    private String _Name = String.Empty;

    /// <summary>The path of the profile</summary>
    public String Path { get { return m_Path; } internal set { m_Path = value; } }
    private String m_Path = String.Empty;

    /// <summary>
    /// Standard cosntructor
    /// </summary>
    public QProfile()
    {
        _Name = String.Empty;
        m_Path = String.Empty;
    }

    /// <summary>
    /// Standard cosntructor
    /// </summary>
    public QProfile(String ProfileName)
    {
        _Name = ProfileName;
        m_Path = String.Empty;
    }
}
Here is the window that shows that the detection is correct:
Image

Here is the generated code:
[ES3PropertiesAttribute("_Name")]
public class ES3Type_QProfile : ES3ObjectType
{
    public static ES3Type Instance = null;

    public ES3Type_QProfile() : base(typeof(Common.Types.QProfile)){ Instance = this; }

    protected override void WriteObject(object obj, ES3Writer writer)
    {
        var instance = (Common.Types.QProfile)obj;
        
        writer.WritePrivateProperty("_Name", instance);
    }

    protected override void ReadObject<T>(ES3Reader reader, object obj)
    {
        var instance = (Common.Types.QProfile)obj;
        foreach(string propertyName in reader.Properties)
        {
            switch(propertyName)
            {
                
                case "_Name":
                reader.SetPrivateField("_Name", reader.Read<System.String>(), instance);
                break;
                default:
                    reader.Skip();
                    break;
            }
        }
    }

    protected override object ReadObject<T>(ES3Reader reader)
    {
        var instance = new Common.Types.QProfile();
        ReadObject<T>(reader, instance);
        return instance;
    }
}

public class ES3Type_QProfileArray : ES3ArrayType
{
    public static ES3Type Instance;

    public ES3Type_QProfileArray() : base(typeof(Common.Types.QProfile[]), ES3Type_QProfile.Instance)
    {
        Instance = this;
    }
}
As you can see, while the read part uses 'SetPrivateField()', which seems to be OK, the write part uses 'WritePrivateProperty()', which seems to be incorrect (and by following it, it really looks for a property, and fail).

Also, in the generated code, there's a couple of suspicious things, but they're probably not a problem:
- '[ES3PropertiesAttribute("_Name")]': It is a field, not a property
- 'foreach(string propertyName in reader.Properties)': Again, it is a field, not a property
- 'switch(propertyName)': Again, it is a field, not a property

To be more precise with namings, when speaking about either a property or a field I've always found it better to refer to it as 'Member'.
User avatar
Joel
Moodkie Staff
Posts: 4825
Joined: Wed Nov 07, 2012 10:32 pm

Re: [bug] Private fields for custom types cannot be written

Post by Joel »

Hi there,

This indeed seems to be a bug with our ES3Type creator and will be fixed in the next update. In the meantime you can fix this by changing the line from "writer.WritePrivateProperty" to "writer.WritePrivateField" in your ES3Types.

With regards to naming, we've actively been avoiding the term "member" because more often than not people interchangeably use the term "property" in our customer support correspondence, and regularly misunderstand the term "member". In terms of serialisation, the term "property" is also used as a definition for any key/value pair serialised to a file, so it makes more sense for us to use this universally. As far as I can remember the only time "fields" and "properties" are externally exposed is via the WritePrivateProperty/WritePrivateField methods, and this will be automatically generated ... well, when the bug is fixed anyway :)

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Gladyon
Posts: 30
Joined: Thu Sep 07, 2017 6:51 am

Re: [bug] Private fields for custom types cannot be written

Post by Gladyon »

Yes, the fix is easy, and as I'm just at the first stages I do not have a lot of things to change so that's not a problem for now.


About the naming, I understand that the first priority is to be understood, you're right about it.
It's just that I spent a lot of time toying with reflection, IL code generation and assembly code modification, so I had to be quite rigid on the namings because I had a lot of properties, fields and methods modification and replacements.
Without it my code would have been totally impossible to maintain even for me. Fortunately I could set the naming standards as I wished because I was alone on this project.
Post Reply