nickbabcock / Pdoxcl2Sharp

A Paradox Interactive general file parser
MIT License
39 stars 13 forks source link

Redundant Keys in Consecutive Elements #33

Closed TommasoBelluzzo closed 8 years ago

TommasoBelluzzo commented 8 years ago

This is not really an issue, but as far as I can see from your readme, there is no way to parse this kind of structures using the automated template you provided (unfortunately I'm still not really mastering your library very well):

traits={
    trait="trait_communal"
    trait="trait_charismatic"
    trait="trait_pc_continental_preference"
}

nebula={
    name="Yinarim Nebula"
    radius=30.000
    galactic_object=124
    galactic_object=208
    galactic_object=249
    galactic_object=350
    galactic_object=547
    galactic_object=645
    galactic_object=958
}

If I produce the following code:

       new Property() { Name = "Traits", Type = "[ConsecutiveElements] IList<string>" },

    case "traits":
        m_Traits = parser.ReadStringList();
        break;

I'll get something like this:

[0] => "trait"
[1] => "trait_communal"
[2] => "trait"
[3] => "trait_charismatic"
[4] => "trait"
[5] => "trait_pc_continental_preference"

And it's a pain to filter the results when reading or reproduce the same structure back when writing. A key-value pair with ReadDictionary would be good, but since the key is always the same it would be redundant. Do you have any suggestion?

[0] => "trait_communal"
[1] => "trait_charismatic"
[2] => "trait_pc_continental_preference"

This is the result I'm expecting to obtain basically. What about implementing another property to the Property class specifiying a redundant key and let the class itself handling everything?

nickbabcock commented 8 years ago

No worries if you can't understand, the API for this library is quite esoteric (good and bad thing). You're pretty close with what you've posted.

var classes = new[] {
    new {
        Name = "Traits",
        Props = new[] {
            new Property() { Type = "IList<string>", Name = "Trait", Quoted = true}
        }
    },
    new {
        Name = "Nebula",
        Props = new[] {
            new Property() { Type = "string", Name = "Name", Quoted = true },
            new Property() { Type = "double", Name = "Radius" },
            new Property() { Type = "IList<int>", Name = "GalaticObjects" }
        }
    },
    new {
        Name = "GameFile",
        Props = new[] {
            new Property() { Type = "Traits", Name = "Traits" },
            new Property() { Type = "Nebula", Name = "Nebula" }
        }
    }
};

Which gets converted into (which you can just copy and paste if you want):

using System;
using Pdoxcl2Sharp;
using System.Collections.Generic;

namespace Pdoxcl2Sharp.Test
{
    public partial class Traits : IParadoxRead, IParadoxWrite
    {
        public IList<string> Trait { get; set; }

        public Traits()
        {
            Trait = new List<string>();
        }

        public void TokenCallback(ParadoxParser parser, string token)
        {
            switch (token)
            {
            case "trait": Trait.Add(parser.ReadString()); break;
            }
        }

        public void Write(ParadoxStreamWriter writer)
        {
            foreach(var val in Trait)
            {
                writer.WriteLine("trait", val, ValueWrite.Quoted);
            }
        }
    }

    public partial class Nebula : IParadoxRead, IParadoxWrite
    {
        public string Name { get; set; }
        public double Radius { get; set; }
        public IList<int> GalaticObjects { get; set; }

        public Nebula()
        {
            GalaticObjects = new List<int>();
        }

        public void TokenCallback(ParadoxParser parser, string token)
        {
            switch (token)
            {
            case "name": Name = parser.ReadString(); break;
            case "radius": Radius = parser.ReadDouble(); break;
            case "galatic_object": GalaticObjects.Add(parser.ReadInt32()); break;
            }
        }

        public void Write(ParadoxStreamWriter writer)
        {
            if (Name != null)
            {
                writer.WriteLine("name", Name, ValueWrite.Quoted);
            }
            writer.WriteLine("radius", Radius);
            foreach(var val in GalaticObjects)
            {
                writer.WriteLine("galatic_object", val);
            }
        }
    }

    public partial class GameFile : IParadoxRead, IParadoxWrite
    {
        public Traits Traits { get; set; }
        public Nebula Nebula { get; set; }

        public GameFile()
        {
        }

        public void TokenCallback(ParadoxParser parser, string token)
        {
            switch (token)
            {
            case "traits": Traits = parser.Parse(new Traits()); break;
            case "nebula": Nebula = parser.Parse(new Nebula()); break;
            }
        }

        public void Write(ParadoxStreamWriter writer)
        {
            if (Traits != null)
            {
                writer.Write("traits", Traits);
            }
            if (Nebula != null)
            {
                writer.Write("nebula", Nebula);
            }
        }
    }

}

If this solves your problem and you like it, I'll add it to the README for future reference

TommasoBelluzzo commented 8 years ago

Awww ok, well it was quite tricky! Thanks man!