Dreaded "Scene graph not updated for rendering" with Indicator

Just added an indicator that is updated when user click on Create New Galaxy and getting the above. :confused:

Things are simply set.
[java]
// [… in constructor of FrontPage class …]
bar = new Indicator(screen, “ProgressBar”, new Vector2f(50f, 50f), new Vector2f(250f, 50f), Indicator.Orientation.HORIZONTAL) {

        @Override
        public void onChange(float currentValue, float currentPercentage) {
        }
    };
    bar.setDisplayPercentage();
    bar.setMaxValue(1f);

// This is called when value has changed.
void changeProgress(float step) {
    bar.setCurrentValue(step);
}

[/java]

I’ll try to see if I can make it work as I’m sure other would have reported this issue if it were generalized. I’ll report on my findings if any.

Hmm…

Got this message:

State was changed after rootNode.updateGeometricState() call. Make sure you do not modify the scene from another thread! Problem spatial name: Gui Node

And also got this one:

State was changed after rootNode.updateGeometricState() call. Make sure you do not modify the scene from another thread! Problem spatial name: null

Extremely weird. -.-

See the difference here?

Problem spatial name: Gui Node
Problem spatial name: null
Just got a third...
Problem spatial name: Base:Node
Base being the UID of the panel on which the whole screen sits.

Something fishy this way come.

If you comment out any of the bar.setXXX calls does the error go away?

At the place where the error goes away can you log the thread and the stack dump?

System.out.println( “Thread:” + Thread.currentThread() );
new Throwable().printStackTrace();

…or whatever.

One of those is bound to show what the issue is.

@pspeed said: If you comment out any of the bar.setXXX calls does the error go away?
Of course it does. :P bar is the Indicator. Before the indicator was there it was working without a problem.
At the place where the error goes away can you log the thread and the stack dump?
Goes away? It doesn't go away. The only way to not have have the crash is by not using the Indicator. Am I misunderstanding the question?

You’re probably thinking this is caused by a threading issue if I get this right. Although it’s possible, I doubt it because I also added a Label that displays what the game does at each stage. In short the game goes like this at each step:

When entering a generation step, I will display the step being worked on: ie: “Generating stars” then in the creation loop (for example) increment at each generated star.

Also, if I comment out the bar.setCurrentValue(…) but leave the hint.setText(…) it works fine; the text gets updated.

Concrete example:
[java]
appStateManager.getState(GuiManager.class).changeHint(java.util.ResourceBundle.getBundle(“Interface/Bundle”).getString(“hntCreateSpiral”));
appStateManager.getState(GuiManager.class).changeProgress(-1);
[/java]

@pspeed said: can you log the thread and the stack dump?

Thread is consistent:

Thread[Game Thread,5,main]

Stack is what I expect and is also consistent.

java.lang.Throwable at com.madjack.games.disenthral.gui.screens.Front.changeProgress(Front.java:220) at com.madjack.games.disenthral.gui.screens.GuiManager.changeProgress(GuiManager.java:114) at com.madjack.games.disenthral.galaxy.Barred.(Barred.java:31) at com.madjack.games.disenthral.galaxy.Galaxy.makeGalaxy(Galaxy.java:121) at com.madjack.games.disenthral.GalaxyBuilder.buildStages(GalaxyBuilder.java:33) at com.madjack.games.disenthral.Overseer.run(Overseer.java:94) at java.lang.Thread.run(Thread.java:722)

So you are modifying the scene graph from a separate thread. You can’t do that.

Yeah ok, I realize that.

But, why now? Only with Indicator? I know, it’s just a rhetorical question, but, I’ve been using this system (I know it’s wrong) since almost day 1, but it’s the first time I get this kind of crash. I’m just… flabbergasted right now.

Theory:
Considering Nifty is considerably slower than t0neg0d’s GUI this never brought any problem. The latter has time to update more stuff and when the LWJGL thread catch up all hell breaks loose…

Anyway. I’ll have to Future it I guess. :confused:

Nifty never used the scene graph directly. So any threading issues would have been hidden away.

Try enqueue’ing the updates to the indicator. Honestly, not sure why this would happen, seeing as all gui Controls are registered via the root… including OSR’s. Aren’t asset loaders run on separate threads? Maybe this is caused by the events beings fired off when the loader is complete as apposed to something sync’d with the main render thread? Total unfounded guess here.

If a node is somehow attached to the main scene graph then it cannot be modified from another thread.

I don’t know enough about what’s going on here to know why that might be confused in some way. But if it’s on screen then it must be a part of the scene graph, right?

@pspeed said: If a node is somehow attached to the main scene graph then it cannot be modified from another thread.

I don’t know enough about what’s going on here to know why that might be confused in some way. But if it’s on screen then it must be a part of the scene graph, right?

Definitely part of the scene graph.

@pspeed said: Nifty never used the scene graph directly. So any threading issues would have been hidden away.

So you’re saying that if I update a nifty control the way I was doing it the engine wouldn’t have crashed because Nifty isn’t using the scene graph? This doesn’t make sense to me. The guiNode would still be in the wrong state and the engine should crash.

There were no crash ever with that message. It is possible that some of the text or some values were skipped, missed on the screen but things go pretty fast when generating a new galaxy and I can’t read most of the message so it’s hard to tell.

I just find it hard to believe that an out-of-thread update to Nifty wouldn’t cause a crash.

On a different topic, threads are not “hightlighted” anymore when there’s a new message posted. Seems to be back to normal. :s

@madjack said: So you're saying that if I update a nifty control the way I was doing it the engine wouldn't have crashed because Nifty isn't using the scene graph? This doesn't make sense to me. The guiNode would still be in the wrong state and the engine should crash.

There were no crash ever with that message. It is possible that some of the text or some values were skipped, missed on the screen but things go pretty fast when generating a new galaxy and I can’t read most of the message so it’s hard to tell.

I just find it hard to believe that an out-of-thread update to Nifty wouldn’t cause a crash.

The reason this is the case is, the GL rendered elements of Nifty are not part of JME’s scene graph. JME has no control over the state of the rendered elements… and doesn’t care one way or the other what state they are in. I believe that JME just cares that Nifty rendered it’s scene and provides JME some rendered final output.

Yeah, both of you are right. I didn’t think this through.

I imagine there is most likely missing text/data when generating a new galaxy. I just didn’t notice it because it’s going too fast.

@madjack said: Of course it does. :P bar is the Indicator. Before the indicator was there it was working without a problem.

Goes away? It doesn’t go away. The only way to not have have the crash is by not using the Indicator. Am I misunderstanding the question?

You’re probably thinking this is caused by a threading issue if I get this right. Although it’s possible, I doubt it because I also added a Label that displays what the game does at each stage. In short the game goes like this at each step:

When entering a generation step, I will display the step being worked on: ie: “Generating stars” then in the creation loop (for example) increment at each generated star.

Also, if I comment out the bar.setCurrentValue(…) but leave the hint.setText(…) it works fine; the text gets updated.

Concrete example:
[java]
appStateManager.getState(GuiManager.class).changeHint(java.util.ResourceBundle.getBundle(“Interface/Bundle”).getString(“hntCreateSpiral”));
appStateManager.getState(GuiManager.class).changeProgress(-1);
[/java]

This IS strange. In the example above, what sort of things are happening in the generation steps? I want to try and reproduce this here to help narrow it down.

EDIT: The “creation loop” you mentioned, how is this loop happening so it doesn’t stop the render loop until it is finished? Is it in the update loop of a control? or? The reason I ask is, when updating a Label, you may just be getting lucky… with the indicator, it is modifying the clipping uniform of the shader used to render it and you would see the error instantly.

@t0neg0d said: This IS strange. In the example above, what sort of *things* are happening in the generation steps? I want to try and reproduce this here to help narrow it down.

I’m pretty sure this isn’t your fault. But, I’ll humor you… :wink:

This particular part of the code is ran when the user click to generate a new galaxy. I send a new hint to the GUI to inform the user what’s going on (think Sim City sort of messages “Reticulating spline” except at this time it’s helpful for me. Well, it WOULD be helpful if things didn’t go so damn fast. :expressionless: That particular message was, iirc, “Generating Spiral Galaxy” translated in the proper language. The second line (-1) reset the nifty progress bar to 0 (it’s a little modification I did to the default control) because we just switched job.

In short, each “job” change the hint to inform the user of what is being done then reset the progress bar to 0. After that we usually enter a loop of some kind until that job is exhausted. Each iteration increments the progress bar (that goes from 0 to 1). Then we switch to a different job.

@t0neg0d said: EDIT: The "creation loop" you mentioned, how is this loop happening so it doesn't stop the render loop until it is finished?

It’s on a different thread. If I stay on the render thread everything stops until it’s done.

@madjack said: So you're saying that if I update a nifty control the way I was doing it the engine wouldn't have crashed because Nifty isn't using the scene graph? This doesn't make sense to me. The guiNode would still be in the wrong state and the engine should crash.

There were no crash ever with that message. It is possible that some of the text or some values were skipped, missed on the screen but things go pretty fast when generating a new galaxy and I can’t read most of the message so it’s hard to tell.

I just find it hard to believe that an out-of-thread update to Nifty wouldn’t cause a crash.

I can only say this so many ways. Nifty does not use the scene graph. This is why there are issues trying to get a Nifty GUI to coexist with things in the guiNode. They are two separate things. Nifty does not use guiNode. Nifty is not connected to the scene graph in anyway. Nifty does not use the scene graph, it does not add nodes, it does not access nodes or geometry that are connected to any viewport or node connected to a viewport.

It’s a scene processor. It manages its own stuff.

Note: that doesn’t mean that it was safe to modify from another thread… just that the nice watchdog that JME uses to detect this would have been bypassed. It would still be possible to have weird errors from nifty by modifying it from a separate thread but you won’t necessarily get a crash unless you modify the structure in a way the nifty was depending on right at that instant.

@t0neg0d said: This IS strange. In the example above, what sort of *things* are happening in the generation steps? I want to try and reproduce this here to help narrow it down.

EDIT: The “creation loop” you mentioned, how is this loop happening so it doesn’t stop the render loop until it is finished? Is it in the update loop of a control? or? The reason I ask is, when updating a Label, you may just be getting lucky… with the indicator, it is modifying the clipping uniform of the shader used to render it and you would see the error instantly.

To be clear: you do understand that he is definitely modifying the scene from a thread other than the rendering thread, right?

That was cleared up really early in the thread so I found the continuing discussion a bit baffling.