Skip to main content

Maintain Node Tree first, then Required Flag

The LionWeb C# framework always keep the nodes in a tree. This means that every node has zero or one parents, and this parent contains the node. As a consequence, simple assignments of containments can have side effects.

note

This only concerns containments. We can freely assign LionWeb references without side effects.

class Person {
...
public IReadOnlyList<Toe> Toes { get; }
public Person AddToes(IEnumerable<Toe> nodes);
public Person InsertToes(int index, IEnumerable<Toe> nodes);
public Person RemoveToes(IEnumerable<Toe> nodes);

public Appendix App { get; set; }
public Person SetApp(Appendix value);
}

...

Toe toe1 = new Toe("t1");
Toe toe2 = new Toe("t2");
Appendix worm = new Appendix("a");
Person john = new Person("g1_X") { Toes = [toe1, toe2], App = worm };
Person sid = new Person("-12");

sid.App = john.App ; <1>
john.App; // throws UnsetFeatureException

Toe firstToe = john.Toes.First(); <2>
Toe lastToe = john.Toes.Last();

sid.AddToes([firstToe, lastToe]); <3>
joh.Toes; // throws UnsetFeatureException

We assign John's App to Sid. For C#, that's just a C# reference -- several places can refer to the same C# object. But for LionWeb, that's a containment, and we must not have two parents for worm! Thus, we detach worm from John, and attach it to Sid:

Now, John's App is null, even though it's required. Consequently, we'd get a UnsetFeatureException in the next line if we tried to get John's App.

We get John's first Toe, i.e. toe1. That's ok, as we only store it in a local variable -- no effect on the tree.

We add several of John's Toes to Sid. Again, we must not have two parents for the same toe, so we detach them from John, and attach them to Sid:

Now, John's Toes are empty, even though the link is required. Consequently, we'd get a UnsetFeatureException in the next line if we tried to get John's Toes.

To summarize, the LionWeb framework always keeps the tree, even if it has to violate required constraints. It helps the developer to adhere to required flags by throwing specializations of LionWebExceptionBase on direct attempts to violate the constraints.

Diagram Legend