Issue #6 wontfix
AdamWorld
created an issue

Hi! When I try to add checkbox in button's click event, following error occurs.

InvalidOperationException: List has changed. at System.Collections.ArrayList+SimpleEnumerator.MoveNext () [0x00000] in <filename unknown>:0

at GUIX.Canvas.Draw () [0x00000] in <filename unknown>:0

at App.OnGUI () [0x00000] in D:\Work\esa\Test\Unity\TestPlayer\Assets\TestEasyPlayer\App.cs:46

AddElement(_myButton); succeeds in Init(). But It fails in other event handler. Did I do sth wrong?

in Button's click event handler

{{{

!c

    GUIX.Button myButton = new GUIX.Button();
    myButton.Rect = new Rect(10.0F, 10.0F, 100.0F, 20.0F);
    myButton.Text = "Click Me!";

    this.AddElement(myButton);

}}}

Regards, Adam.

Comments (6)

  1. Jeremy Hollingsworth repo owner

    Adding or removing an Element within the event handlers is generally not supported. The event handlers are called from the update pass, and in the case of rendering via a Canvas or the Manager the updates are done from a loop.

    Adding an Element to that modifies the array that is currently looped over. Hence the errors you are seeing.

    Anyway, instead of adding the Element directly in the handler, in the handler push the new Element into a custom List and later when outside the handler loop through the list and add them all. I was thinking of adding this type of deferred access to the base system, but doing it for everything results in needless memory use, etc.

  2. AdamWorld reporter

    Hi! JeremyHollingsworth Thank you for your reply.

    I wanted to add Window for modal/modaless Dialog. If adding element is needless, could you tell me how to run modal/modaless dialog in button's click.

    Regards, Adam.

  3. Jeremy Hollingsworth repo owner

    As long as you don't add it from inside the draw loop for the parent Element (and event handlers are fired from that loop), you can do it. You just need to defer it. One way that I mentioned is pushing your new Element to a list from within the event handler, and later checking that list and adding what you need to in one go.

    Also, usually for these situations you want to create a single mechanism to handle your dialogues for specific lists, menus, etc. In that case, you would call methods on your dialogue mechanism from your event handlers. This provides decoupling, reduces the likelihood of errors down the road and allows for more maintainable code. If you need to change how dialogues work, you just need to change the code in one place, not in every event handler that uses it.

    This way you only ever create one window for all those modal dialogues - your call from the method handler shows it and passes the information you need to show, etc.

    At least that's what I recommend, you may find another way that works better for you. ;-)

  4. Log in to comment