Passing JME objects to class instances

Hello,

The following has been bugging me for quite a while. Lets say that I have a simple main class that extends simpleApplication and does some basic stuff like generate a floor and a cube and puts on a texture and rigidBodyControl
on each of them. Now let’s say that I have another class called cubeGenerator and I want it to generate the cubes instead of doing it in the main class. The cube generation is something like this:

public void generateCube(float x, float z) {
    Spatial testCube = GeometryGenerator.makeCube(this.app, "testcube", ColorRGBA.White, assetManager.loadTexture("Textures/Microscheme.png"), cubeSizeDiv2);
    testCube.setLocalTranslation(x, cubeSizeDiv2, z);
    terrain_phy = new RigidBodyControl(CollisionShapeFactory.createBoxShape(testCube), 0.01f);
    testCube.addControl(terrain_phy);
    terrain_phy.setFriction(0.1f);
    bulletAppState.getPhysicsSpace().add(terrain_phy);
    arenaNode.attachChild(testCube);
    terrain_phy.setKinematic(true);
}

As you can see, it requires and instance of : AssetManager, BulletAppState , terrain_phy (defined in main class), and arenaNode(defined in main class) . How do I pass all of these from the main class to the cubeGenerator constructor?
do I do:

public MazeGenerator(Application app, BulletAppState bulletAppState, Node arenaNode, RigidBodyControl terrain_phy, AssetManager assetManager) {
    this.app = app;
    this.bulletAppState = bulletAppState;
    this.arenaNode = arenaNode;
    this.terrain_phy = terrain_phy;
    this.assetManager = assetManager;
}

or do I just do (in other words write getters for all the objects in the main class and just pass an instance of it):

MazeGenerator( SimLanucherMain simLauncherMain) {
   this.app = simLauncherMain.getApp()
   etc.......
   ..........
}

Which way is the ‘better’ way (if any of the above) to do it in terms of future flexibility, correct structuring and speed?
Will it slower and take more memory if I pass the whole instance of my main class to another class than if I pass individual objects? Thanks in advance.

Both are valid solutions actually, it really dependy on your programming style.

Yes, both are valid. There shouldn’t be any impact memory or speed wise.

I prefer the second way (passing one object, which contains all references), because it creates code that is easier to maintain: If at any time in the future you decide that you need additional references in the constructor, you can just get them out of the passed object reference without the need to modify all calls to this constructor.

At some point you’ll discover how to use classes for more than “separating your code” anyway and come up with even better ways to organize your code. For factory type classes I’d actually mostly use static methods but your example is quite specific with its need for special nodes and whatnot.

bulletAppState can already be easily retrieved from Application… as can AssetManager. So you already have two redundant parameters in there.

…and if your MazeGenerator was an app state then it would already be provided application during its initialize() method… so then you’d only have to pass arenaNode and the control (unless the control is on the arena node and then you don’t have to pass that either).

Or you have an ArenaAppState which is what created the arena and also has the generateMaze() method internal.

There are a 100 different ways to organize your game but most of them will be kind of kludgy-feeling until you learn some of the constructs the engine provides to make your life easier. (app states, controls, etc.)

@pspeed:
I read about app states a week back from the tutorials but I haven’t gotten a ‘feel’ for them yet. I know I can get the AssetManager from the Application but I couldn’t get the bulletAppState. So I guess I’ll just pass in my Application and retrieve the rest from there.

@normen
Yes for factory classes I use static methods but for more complicated objects I still have to somehow pass the appropriate instances to them.

Thanks for the answers, looks like I’ve still got alot to learn.

Well if we are what we prefer, I publish those objects to a DependencyInjection context, and then whenever I need one I can let it inject.
Performacne wise this is minimal slower, but usually the stuff like generators are rather longlived, and can just keep those into fields.

1 Like