Custom AppStates in the SDK, please test

Hey,

I finally came around to adding Custom AppStates in the SDK (similar to Custom Controls). I call it the mother of all SDK features cause it will open up some serious possibilities for the SDK and its general use cases.

Its the first implementation and I am sure theres bugs and issues with it but if you dare you can try around with it in nightly now. Its also at the moment probably a good way to break something in the SDK’s SceneComposer severely if you try hard :smiley:

Features/Limitations

  • Separate Explorer allows adding AppStates from the projects code or libraries to an opened scene
  • Gives AppStates access to a fake, safe SimpleApplication, all with assetManager and other features like GUI Node
  • Fake application has not all features of full application (partially this will change, partially its inherent with the method)
  • Shows any compatible beans properties of the AppState (getter/setter pairs with corresponding field) in the Properties window, editable live

Usage:

  • Open a j3o scene
  • Go to the AppStateExplorer
  • Press the “attach…” button
  • Select an AppState from your code or enter a full class name in the browser that opens
  • Select the AppState to see any compatible beans properties

Example use cases:

  • Complete coding of games in the SDK with all tools like SceneExplorer etc. to see and influence whats happening.
  • Create an AppState that spawns your NPCs (with their custom Controls ^^) or other code to test a level.
  • Write some simple AppStates initialize() code to set up a scene (all with your projects assets and classes), then save it as j3o, right in the SceneComposer.

Known Issues:
- Sometimes when first adding a new class, the class has to be compiled and the SDK restarted for the file to be recognized
- The AppStateExplorer has to be open when the scene opens to work.
- You can halt the SDK with an infinite loop

  • You have to press the “update” button in the SceneExplorer to see changes in the scene.
  • The save button might not light up right away when you change the scene via an AppState and you might have to change a detail in the scene via the “normal” tools to be able to actually save it.
    - The getter methods of the AppStates should be thread safe in the sense that they should not trigger thread sensitive things, the calling thread isn’t guaranteed yet. The setters are always called from the update loop thread.
  • Esp. accessing views, renderer etc. will atm. behave strangely, partially this cannot be fixed or only at a later point

I’m sleepy and tired and will update this with some more info later, hope you manage to have some more fun with it than I managed to today :wink:

Cheers,
Normen

10 Likes

Brilliant!

That sounds sweet! I’m gonna play around with it tonight =)

Nice one !

Created a little quixote test project to show possibilities of this new game-editor interaction for the SDK, especially for examples and newbies :smiley: (see updated pic above for screenshot, also note some of the updated “known issues”)

Instructions:

  • Open project
  • Build
  • Open AppStateExplorer
  • Open Scenes/ShootOut.j3o
  • Open ConfigAppState in AppState Explorer
  • Enjoy reading the code and thinking how this can be used further :wink:

@normen Hmm, are you sure you uploaded the correct demo project?

  1. There is no scene named Scenes/ShowOff.j3o (although there is on called ShootOut.j3o) which cannot be opened.
java.lang.NullPointerException
	at com.jme3.scene.Spatial.clone(Spatial.java:1174)
	at com.jme3.scene.Node.clone(Node.java:563)
	at com.jme3.scene.Node.clone(Node.java:60)
	at com.jme3.scene.Spatial.clone(Spatial.java:1161)
	at com.jme3.scene.Node.clone(Node.java:563)
	at com.jme3.scene.Node.clone(Node.java:60)
	at com.jme3.scene.Spatial.clone(Spatial.java:1161)
	at com.jme3.scene.Node.clone(Node.java:563)
	at com.jme3.scene.Node.clone(Node.java:60)
	at com.jme3.scene.Spatial.clone(Spatial.java:1161)
	at com.jme3.scene.Node.clone(Node.java:563)
	at com.jme3.scene.Node.clone(Node.java:60)
	at com.jme3.scene.Spatial.clone(Spatial.java:1201)
	at com.jme3.scene.Spatial.clone(Spatial.java:66)
	at com.jme3.asset.CloneableAssetProcessor.createClone(CloneableAssetProcessor.java:48)
	at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:321)
	at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:368)
[catch] at com.jme3.gde.core.assets.SpatialAssetDataObject.loadAsset(SpatialAssetDataObject.java:90)
	at com.jme3.gde.scenecomposer.OpenSceneComposer$1.run(OpenSceneComposer.java:38)
	at java.lang.Thread.run(Thread.java:722)
  1. There is no ControlAppState class available in that zip-file.

Yeah, I put the names completely wrong here but I can open the j3o…

So, I played around with this in a normal RC2 install with nightly updates enabled and at first my local project worked, the zip export not… When looking for why I found it out: Somehow new classes are only registered when the project is first opened, you have to restart the SDK to make it scan the classes again. So the solution to use the project would be first compiling, then restarting the SDK. After that new compiles should be registered so if you reopen the j3o or AppState the new classes will be in effect.

So, something to work on for me, the base systems for scanning classes etc. are relatively fresh and came with the Custom Controls feature. Guess it can be improved :wink:

Ah, I guess I did not try a SDK reboot… now it works! =) I can open the ShootOut.j3o and it looks fine =)

1 Like

I think I found the issue. Because the “build/classes” folder doesn’t exist when the project is first created its not part of the list of source folders I get for that project. So theres also no listener registered on it to check if there was changes in that folder :slight_smile: Hence a rescan is never triggered if the build/classes folder wasn’t there in the first place… Fixed that in svn and also added a generally more robust change check.

1 Like

I did a major overhaul of the node system and how it reads/writes its data and issues change events. This should avoid some strange issues with freezes and maybe also some random scene errors as the threading is much more straight now. This also makes the getter calls for Controls and AppStates be called from the right thread at all times.

Finally, this allows the SDK to sense changes in the scene even if they were not initiated by the SDK :slight_smile:

Theres some issues with reading enum values still though.

http://code.google.com/p/jmonkeyengine/source/detail?r=10083

3 Likes

Again a great job from normen, you must work as professional developer and not music !

Thanks for your work and this brilliant idea !

@soaring said: Again a great job from normen, you must work as professional developer and not music !

Thanks for your work and this brilliant idea !


Hehe, thanks, I’m flattered :slight_smile: Though its quite easy to improve a mess you created yourself :wink: Some parts of the SDK have really been done quick’n’dirty as I wanted to get the whole package / point of the SDK across. Kirill put my obsessive self in a bad situation of “you gotta get this working, people will use it” by deciding we’d bundle the SDK and the engine ^^

But I have to say I am quite pleased with the results by now. The deployment to different platforms, model import, editing of particles etc… I knew I (and everybody else) would implement that anyway when I’d go at actually doing a game, just like I did for jME2. I think the SDK is for many people replacing all those little tools and its by now even growing up to be comparable to the commercial packages like UDK and Unity, given how much more powerful the engine also grew beneath it :slight_smile:

But yeah, theres still a few things to clean up… Its kind of hard getting together the logic of a 3d engine, a swing editor framework and the general idea of “creating games” but we’ll crack that nut, I swear :wink:

So… @all, I am running into a logic/usability issue that I think I have the answer to, still I want to put it out here.

Currently, the rootNode of the fake application you work with is the same node as the loaded model. This means that from the perspective of the AppState there is no rootNode that the model is attached to but only the model node. While this is intuitive when looking at the scene and coding the AppState, I guess its less so when actually working with the scene and AppState later. When you have an application you could of course replace the rootNode with a loaded j3o but I guess that really makes no sense at all.

So in the end I guess the AppStates should get the “real” rootNode of the application, this way it makes most sense structurally. This would of course bring some usability/intuitiveness issues. For example you can attach stuff to the rootNode but you cannot save it in the editor or j3o. Of course this could be deemed a feature, in the current example Quixote will be saved in the j3o when you hit save while he’s running. Further you have to know the name of the scene you load to get the model. On the other hand that model is at the same time the only attached spatial to the root node when you open a model, so not exactly a problem either.

So, I say “real rootNode instead of model node”, k?

Btw, just because its so much fun I added TextureAtlas batching to the SDK (fixed 4096 texture size for now) and made the geometry batching undo work :wink: So you can now batch geometry even if it has different textures and also undo if you falsely batched/optimized a part of the scene.

Err… this was meant to go here ^^

I added starting via the java file and editor menus :wink: I also fixed most bugs that were left, see the updated first post. It now nicely updates every 1s when the scene changes. For now only the selected node is scanned “live” and scene change don’t trigger the save button (because of that).

1 Like

I updated the ControlsDemo.zip to a nice generic demo of jMEs Controls and AppStates I think, works with the latest nightly and AppState features but should also run as a normal jme project in a stable SDK (I cannot run jme applications on OSX atm, only the SDK ;)).

Hi @normen,

Sorry to dig up this old thread but i’m interested in this feature…

- Write some simple AppStates initialize() code to set up a scene (all with your projects assets and classes), then save it as j3o, right in the SceneComposer."
I need it for place custom particles emitter(and other custom geometries) in my scenes and i have in mind a clone of nifty xml visualisation for my gui lib too. I'm currently stucked with the saving option.

As a try, i have a simple scene (.j3o) with a flat terrain created by the SDK and i want to add a sinbad model (.j3o) via appState.
When i load the appState, everything seems ok, sinbad is there.

How do you save sinbad model into the scene for the next time ?

  • convert to j3o binary doesn’t work
  • save button is not accessible so, as you suggest
    - The save button might not light up right away when you change the scene via an AppState and you might have to change a detail in the scene via the “normal” tools to be able to actually save it.

    …i change sinbad position then i can save…nothing happens too

…sinbad is not saved in the scene when i reopen it.

Did i missed something or is it bugged for you too?

I’ve already tried to use the binary exporter manually with an action listener in the appState but the “fake” application used doesn’t allow me to do that…

I know i could do it online with my whole application but it could be usefull to load only that part without compiling others during color testing or textures modifications…

No, I can save the scene when I changed it.

Arf, if you add a simple cube geom like that :
[java]
public class testEmitterState extends AbstractAppState {

@Override
public void initialize(AppStateManager stateManager, Application app) {
    super.initialize(stateManager, app);
    Box b = new Box(1, 1, 1);
    Geometry geom = new Geometry("box", b);
    Material boxMat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
    boxMat.setColor("Color", ColorRGBA.Red);
    geom.setMaterial(boxMat);
    geom.setLocalTranslation(0, 5, 0);
    ((SimpleApplication) app).getRootNode().attachChild(geom);
}

}

[/java]

when you click on save, it is saved in your scene when you reopen it…i don’t understand what i miss :-?

You attach stuff to the rootNode and not to you model node, see this post from this very thread:
http://hub.jmonkeyengine.org/forum/topic/custom-appstates-in-the-sdk-please-test/#post-200968

1 Like