Skip to content

Can't modify nodes using C#? #55

Open

Description

@Nadav-Ruskin

Hello,

Thank you for developing this tool.

I'm trying to use cwtools to programmatically edit Clausewitz files.

Running the tests in CWToolsCSTests, I've noticed that the tests fail to modify the leaves.

            //Parse event file
            // var parsed = CWTools.Parser.CKParser.parseEventFile("./testevent.txt");
            var text = File.ReadAllText("./testevent.txt");
            var parsed = CWTools.CSharp.Parsers.ParseScriptFile("testevent.txt", text);

            var eventFile = parsed.GetResult();

            //"Process" result into nicer format
            // var processed = CK2Process.processEventFile(eventFile);
            var processed = CWTools.CSharp.Parsers.ProcessStatements("testevent.txt", "./testevent.txt", eventFile);

            //Find interesting event
            var myEvent = processed.Nodes.FirstOrDefault(x => x.TagText("id") == "test.1");

            //Add is_triggered_only = true
            var leaf = new Leaf(KeyValueItem.NewKeyValueItem(Key.NewKey("is_triggered_only"), Value.NewBool(true), Operator.Equals), FSharpOption<range>.None);
            myEvent.AllChildren.Add(Child.NewLeafC(leaf));

The last line results in a no-op, as the list refuses to be modified and C# won't tell me why. Any ideas on how to circumvent this?

Activity

  1. tboby commented on Jul 11, 2023

    @tboby
    Member

    Hi!

    You're right, the interface has changed since then so that snippet doesn't work.

    I've updated it so it works again.

    Basically, most of the properties return read-only copies as F# has immutable data by default. There are four ways you can actually modify the data structure:

    1. SetTag which will look for the key and replace it, or add it if it isn't there
    2. AllChildren's setter, which takes a C# List and replaces all current children with it
    3. All's setter, which takes an F# List and replaces all current children with it it
    4. `AllArray', which returns a mutable array (but not resizable), or the setter which replaces all current children with it

    For "Leaf", both the Key and Value have setters. For "Node", the Key has a setter too.

                //Add is_triggered_only = true
                var leaf = new Leaf(KeyValueItem.NewKeyValueItem(Key.NewKey("is_triggered_only"), Value.NewBool(true), Operator.Equals), FSharpOption<range>.None);
                myEvent.SetTag(leaf.Key, Child.NewLeafC(leaf));
                // or
                // var newChildren = myEvent.AllChildren;
                // newChildren.Add(Leaf.Create(KeyValueItem.NewKeyValueItem(Key.NewKey("is_triggered_only"), Value.NewBool(true), Operator.Equals), range.Zero));
                // myEvent.AllChildren = newChildren;
    

    Hope that helps a little!

  2. Nadav-Ruskin commented on Jul 13, 2023

    @Nadav-Ruskin
    Author

    Thank you for the in-depth answer!

    Speaking of serializing, I have another question. I'm trying to modify a Crusader Kings III file programmatically and iteratively, and since the file is quite big I'd like to pickle the parsed data between runs. Is there a way to do so?

                var processed = CWTools.CSharp.Parsers.ProcessStatements("testevent.txt", "./testevent.txt", eventFile);
    
                var serialized_processed = JsonSerializer.Serialize(processed);  // <--- Fails here: 			System.NotSupportedException: 'F# discriminated union serialization is not supported. Consider authoring a custom converter for the type.'
                var deserialized_processed = JsonSerializer.Deserialize<Node>(serialized_processed);
                File.AppendAllText("./serialized_node.txt", serialized_processed);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions