About jme3 methods you shouldn't call from user code...(?)

There are not few methods in jme3 that state in the javadoc that they should not be called from user code. I’m wondering why these methods are not made private or package protected or something like this?

There are also seemingly inconsistencies to that above. When you extend Application directly it looks like you have to call AppStateManager#update(float) from user code although javadoc says you shouldn’t, right?

So all in all I’m asking for advice or general rule when to ignore “don’t call from user code” and when not?

Well basically when you look for a method to do some usual stuff and find those a good choice normmaly dont use them.



There are exceptions however. Like some of the MEthods need to be called from plugins or in special cases where it makes sense to call them, thus they are public.



If you really think one of those methods is the correct, make sure that you really understand all consequences and sideeffects this will cause.

You should not call update() from user code, as its stated. Try reading the beginner tutorials, maybe it becomes clearer then :roll: The method needs to be public so the render system can call it.

normen said:
You should not call update() from user code, as its stated. Try reading the beginner tutorials, maybe it becomes clearer then :roll: The method needs to be public so the render system can call it.

I wanted to start out with Application instead of SimpleApplication. So what I did was copying parts from SimpleApplications to my "user code" as example code how to correctly extend Application.
So my update loop looks like this now and stateManager.update(tpf); is effectively user code (?):
[java] @Override
public void update() {
super.update(); // makes sure to execute AppTasks
if (speed == 0 || paused) {
return;
}
float tpf = timer.getTimePerFrame() * speed;
controls.update(timer);
// update states
stateManager.update(tpf);
// call user code e.g. simpleUpdate(tpf)
updateUpdatables(tpf);
rootNode.updateLogicalState(tpf);
guiNode.updateLogicalState(tpf);
rootNode.updateGeometricState();
guiNode.updateGeometricState();
// render states
stateManager.render(renderManager);
if (context.isRenderable()) {
renderManager.render(tpf);
}
// Call user code e.g. simpleRender(renderManager) and/or
// make advanced modifications to frameBuffer and scene graph.
stateManager.postRender();
} [/java]
And by the way the call to updateUpdatables(tpf); calls a list of objects implementing my interface Updatable so the update logic can be implemented distributed in my objects and no logic is in the update method directly. Is this something you would actually do by adding objects implementing AppState or is this something different?

PS: No offense but docs are not really helping me much since they are more like little code snippets and you can't relly learn from them how to get structure in you app. I actually read a lot here but I still spend 10 times more time with trying out stuff because a lot of stuff stays unclear to me.

Well I use this for one of my projects, and have no problems with it, tho it is kinda a hughe modification of te Simpleapplication one



[java] @Override

public void update() {

if (client != null) {

client.Update();

}



TimedInvocation.Update();

super.update();

float tpf = timer.getTimePerFrame() * speed;

stateManager.update(tpf);



consoleCommands();

SceneSwitch.update(tpf);



ControllerManager.getInstance().update();





rootNode.updateLogicalState(tpf);

rootNode.updateGeometricState();

SceneSwitch.updateStates(tpf); //geometrystate update on seperate rendertotexture nodes, cause else they never recive one.

renderManager.render(tpf);

GUIManager.update(tpf);



this.audioRenderer.update(tpf);



if (showStatistics) {

secondCounter += timer.getTimePerFrame();

int fps = (int) timer.getFrameRate();

if (secondCounter >= 1.0f) {

// BufferUtils.printCurrentDirectMemory(null);

fpsText.setText("Frames per second: " + fps);

secondCounter = 0.0f;

}

}



}[/java]

Then I guess starting out with code copied from SimpleApplication class is not a bad thing. :slight_smile:



But still, is my approach to making an Updatable interface correct or should I implement AppState for that?





[java]

public interface Updatable {



public void update(float tpf);



}

[/java]





[java] private void updateUpdatables(float tpf) {

for(Updatable u : updatables) {

u.update(tpf);

}

}[/java]





[java] public void addUpdatable(final Updatable updatable) {

enqueue(new Callable<Void>() {



@Override

public Void call() throws Exception {

updatables.add(updatable);

return null;

}



});

}[/java]

And thanks for the really fast help in the forum I’m not used to that… :slight_smile:

Seems fine for me so far. (Also you usally get quite fast responses here, we all have boring stuff to do at work/studies and refresh to get a few seconds away from it often XD ^^

EmpirePhoenix said:
Seems fine for me so far. (Also you usally get quite fast responses here, we all have boring stuff to do at work/studies and refresh to get a few seconds away from it often XD ^^

So true ;)

@douter
Those methods are there and public because they have to be called by inner classes but not by users. We assume that people will use simpleApplication and not Application directly. But you can of course.
Maybe the javadoc could state "users don't have to use this method most of the time" :p

Also there are empty constructors for serialization that have to be public but users should not use them as they construct "incomplete" objects.

Also some methods have to be public because we can't use the protected scope when classes are in different package, and we don't want the engine to be a package mess.

I’d suggest not directly extending Application at all but to always use SimpleApplication.

I think SimpleApplication is poorly named… though really too late to change it. I feel like some people think it’s limiting them in some way when in fact it should be the place everyone starts.

1 Like
douter said:
Then I guess starting out with code copied from SimpleApplication class is not a bad thing. :)

But still, is my approach to making an Updatable interface correct or should I implement AppState for that?


[java]
public interface Updatable {

public void update(float tpf);

}
[/java]


[java] private void updateUpdatables(float tpf) {
for(Updatable u : updatables) {
u.update(tpf);
}
}[/java]


[java] public void addUpdatable(final Updatable updatable) {
enqueue(new Callable&lt;Void&gt;() {

@Override
public Void call() throws Exception {
updatables.add(updatable);
return null;
}

});
}[/java]


Yeah, I think you'd be better of with app states in this case since then you get life-cycle methods built in. And adding app states is already thread safe.
pspeed said:
I think SimpleApplication is poorly named... though really too late to change it. I feel like some people think it's limiting them in some way when in fact it should be the place everyone starts.

Thumbs up on that, agree completely.

I don’t blame whoever named it though, the simple part was to denote that its simpler to use than Application, but the feeling a lot of people get is “I’m a simplified version of Application”. But i think that it’s used so much (in all tutorials and all tests) that people should know to use it.

pspeed said:
I feel like some people think it's limiting them in some way when in fact it should be the place everyone starts.

It is a misnomer. I did the same mistake when I started but after a while I realized that I was pretty much doing the exact same thing that Application was doing, so after putting some thought into it, I went back to SimpleApplication. Much easier to deal with.

SimpleApplication means "Simpler to use", not "Limited in use" and we all need more simplicity. :)