Is it in any plan? Wouldn’t be an issue to delay for a frame I guess from my side of the fence.
I’ll use enqueue for now, but it would be really nice if it was thread-safe.
Is it in any plan? Wouldn’t be an issue to delay for a frame I guess from my side of the fence.
I’ll use enqueue for now, but it would be really nice if it was thread-safe.
@madjack said: Is it in any plan? Wouldn't be an issue to delay for a frame I guess from my side of the fence.I’ll use enqueue for now, but it would be really nice if it was thread-safe.
Could you give me an example of how/why your updating from another thread? And is the error you are getting the usual “scene has been modified” yadda yadda?
I send messages to the server that broadcast them.
Network listener gets message, tries to print it. I get a crash.
I’ve gotten the “rootNode modified after update” and also a couple of other weird crashes. Only 1 I copied:
Exception in thread "Server" java.lang.NullPointerException at com.jme3.font.Letters.getCharacterSetPage(Letters.java:277) at com.jme3.font.BitmapTextPage.assemble(BitmapTextPage.java:131) at com.jme3.font.BitmapText.assemble(BitmapText.java:407) at com.jme3.font.BitmapText.getHeight(BitmapText.java:227) at tonegod.gui.controls.extras.ChatBoxExt.rebuildChat(ChatBoxExt.java:390) at tonegod.gui.controls.extras.ChatBoxExt.updateChatHistory(ChatBoxExt.java:373) at tonegod.gui.controls.extras.ChatBoxExt.receiveMsg(ChatBoxExt.java:366) at com.ochlocracy.game.gui.screens.GameScreen.printChatMessage(GameScreen.java:243)
Using app.enqueue totally fixes the problem. But honestly I’d prefer if I didn’t have to enqueue. If you can’t be bothered, don’t want to, etc, it’s fine. Just being curious if it’s in the plans or not.
I’ll certainly look into the possibility, just not sure how I can circumvent the issue in a different way than JME does currently. The entire library is based on the JME scene graph (i.e. all components are Nodes). Any pointer in a direction that could make this work differently would be appreciated!
As for the error above. That’s an odd one. Well… I can at least guarantee you’ll never see that error again when I move the library over to TextElement and stop using BitmapText.
The gui is like the scene, it’s not thread safe because it’s updated in the render thread.
If you want to update it from another thread yo have to use the exact same way as you would with the scene. Use callable and enqueue their execution to the application.
The only suggestion I can think of off the top of my head is to defer any changes to the update method. For that you would need a concurrent list or something to hold any changes between frame or whatever.
But obviously I haven’t put -any- thoughts into this, thus you can quickly discard my opinion.
@madjack said: The only suggestion I can think of off the top of my head is to defer any changes to the update method. For that you would need a concurrent list or something to hold any changes between frame or whatever.But obviously I haven’t put -any- thoughts into this, thus you can quickly discard my opinion.
Yeah, this would have the same impact as enqueueing all updates by default. I know it’s a bit of a pain to have to enqueue these messages, but I think the alternative will have a worse effect overall. I may be able to do this specifically for the ChatBox controls. This is the one control that would/could/should expect updates to come from another thread.
I guess that would make sense. But, do as you think is best. It’s not an obligation.
Is it acceptable for me to hint that received network messages that directly modify the scene graph (or UI) may be a sign of a design problem that will bite you later?
Given that frames and network messages are so completely decoupled it generally makes more sense to share some kind of thread-safe state that the two use. I don’t know the specifics in this case, but even just enqueuing can be a little ‘dangerous’ since rendering may be tied up for some reason and network traffic may be bursty. In the worst case you could end up enqueuing several hundred Callables all updating the same target.
Otherwise, if you don’t care about threading then you can just create a message queue for all network traffic and handle the messages on the render thread. If you are using SpiderMonkey then you can even defer all message delivery this way by managing your own MessageListenerRegistry. I don’t recommend this approach really but I also don’t see it as markedly worse than enqueuing every scene change.
For having played tens of MMOs, some with very high population, chat traffic won’t be a huge issue. Considering we’ll have a max population of 100 and server-generated message will be low, I’m thinking less than a dozen of messages every second at the absolute worst of normal operation.
For now we don’t need more than this, but there’s definitively a message queue scheme I’m keeping in the back of my head when the need arise. For now the important is to have some chat working.
The issue I posted was more of an afterthought after realizing the issue was there. Not because I lack the ability to find a fix.
Ok… I’ll add a secondary way of adding a new message to the control. I’ll keep what is currently there and then provide a secondary that will enqueue what you hand it. This way, you (or whoever) are not tied to using this if you decide on handling things in a different way.