Any chance we can drop singletons in favor of some IoC? That is:
TextureBag textureBag = TextureBag.getInstance();
// becomes
@Inject
TextureBag textureBag;
There is currently no plan to use a DI/IoC container in xith. While I agree with you that it would be nice, it would require a radical change in the engine API. I do however use Pico with custom injectors in my game to implement game states:
public class Menu implements GameState
{
private HUD gui;
private BranchGroup scene;
private RenderPass renderPass = null;
private Panel mainPanel;
private ModelAnimation[] avatarAnims;
private MD2Model avatarModel;
private GameContext context;
// <editor-fold defaultstate="collapsed" desc="Dependencies">
@Required
public void setSceneGraph( SceneGraph sceneGraph )
{
this.sceneGraph = sceneGraph;
}
protected SceneGraph sceneGraph;
@Required
public void setCanvas( Canvas3D canvas )
{
this.canvas = canvas;
}
protected Canvas3D canvas;
@Required
public void setGameManager( GameManager gameManager )
{
this.gameManager = gameManager;
}
protected GameManager gameManager;
@Required
public void setResourceLocator( ResourceLocator resourceLocator )
{
this.resourceLocator = resourceLocator;
}
protected ResourceLocator resourceLocator;
@Required
public void setInputSystem( InputSystem inputSystem )
{
this.inputSystem = inputSystem;
}
protected InputSystem inputSystem;
@Optional
public void setController( Controller controller )
{
this.controller = controller;
}
protected Controller controller;
@Required
public void setScheduler( OperationScheduler scheduler )
{
this.scheduler = scheduler;
}
protected OperationScheduler scheduler;
@Required
public void setMd2Loader( MD2Loader md2Loader )
{
this.md2Loader = md2Loader;
}
protected MD2Loader md2Loader;
@Required
public void setLevelManager( LevelManager levelManager )
{
this.levelManager = levelManager;
}
protected LevelManager levelManager;
// End dependencies </editor-fold>
@Initializer
public void initialize()
{
try
{
scene = new BranchGroup();
setupBackGround();
setupGui();
}
catch( Exception exception )
{
exception.printStackTrace();
}
}
public void enter( GameContext context )
{
this.context= context;
sceneGraph.addHUD( gui );
scheduler.addAnimatableObject( avatarModel );
renderPass = sceneGraph.addPerspectiveBranch( scene );
sceneGraph.getView().lookAt( -30,30,-30, -10,10,-10, 0,1,0 );
}
public void leave( GameContext context )
{
scheduler.removeAnimatableObject( avatarModel );
sceneGraph.removeHUD( gui );
sceneGraph.removeBranchGraph( scene );
sceneGraph.removeRenderPass( renderPass );
}
// (...)
}
So my main class more or less only consists of registering components to the container:
MutablePicoContainer container = new DefaultPicoContainer( new Caching().wrap( new CombinedInjection() ) );
container.change( Characteristics.CACHE );
container.addComponent( this );
container.addComponent( Shutdown.class );
container.addComponent( container );
container.addComponent( env );
container.addComponent( physEng );
container.addComponent( collEng );
container.addComponent( gfxManager );
container.addComponent( resLoc );
container.addComponent( md2Loader );
container.addComponent( inputSystem );
container.addComponent( getOperationScheduler() );
container.addComponent( env.getCanvas() );
container.addComponent( activeController );
container.addComponent( EntityManager.class );
container.addComponent( GameManager.class );
container.addComponent( LevelManager.class );
container.addComponent( Editor.class );
container.addComponent( Intro.class );
container.addComponent( Menu.class );
container.addComponent( Settings.class );
container.addComponent( LevelEngine.class );
container.addComponent( Outro.class );
container.addComponent( TestJAXB.class );
container.addComponent( ThreadManager.class );
gameManager = container.getComponent( GameManager.class );
gameManager.switchTo( Intro.class );
I want to make a blog article about this soon.
That looked very ugly and dangerous from a thread-safety point of view.
Xith is designed to be single threaded while rendering. You can do your math in an off-render-thread but have to make sure yourself to get the results to the rendering thread in a thread safe manner. Usually you use ScheduledOperations for this.