threerings/playn — pull request #66 by tomfisher (2014-12-03 11:07:34+00:00)
Title: Bind the platform's lifecyle to the game controller

Expose PlayN as a normal iOS view controller and bind the game lifecycle with it. This also makes both integration and customisation easier, which always happens in a view controller.

RoboGameController could be more accurate name than RoboRootViewController which may or may not be a root view controller now in the current context and sounds a little bit confusion. I did not change that for the sake of patch reviewing.

I'v tested with my application and also wrote a simple application demonstrating how to use PlayN as a standalone application or an embedded application. Probably it should be included in the play-smaples project.

public class Main {

public static void main(String[] args) {
NSAutoreleasePool pool = new NSAutoreleasePool();
UIApplication.main(args, null, StandaloneApplication.class);
// UIApplication.main(args, null, EmbeddedApplication.class);
pool.close();
}

public static class StandaloneApplication extends UIApplicationDelegateAdapter {
private UIWindow window;
@Override
public boolean didFinishLaunching(UIApplication app, UIApplicationLaunchOptions launchOpts) {
window = new UIWindow(UIScreen.getMainScreen().getBounds());
RoboRootViewController gameController = new RoboRootViewController();
gameController.run(new GameDemo());
// Setup our game controller as the root controller
window.setRootViewController(gameController);
window.makeKeyAndVisible();
addStrongRef(window);
return true;
}
}

public static class EmbeddedApplication extends UIApplicationDelegateAdapter {
private UIWindow window;

@Override
public boolean didFinishLaunching(UIApplication app, UIApplicationLaunchOptions launchOpts) {
window = new UIWindow(UIScreen.getMainScreen().getBounds());
UINavigationController root = new UINavigationController();
root.addChildViewController(new WelcomeViewController());
// Setup a navigation controller as the root controller to manage the application.
window.setRootViewController(root);

window.makeKeyAndVisible();
addStrongRef(window);
return true;
}
}

public static class WelcomeViewController extends UIViewController {

public WelcomeViewController() {
super();
UIButton button = new UIButton();
button.setTitle("Run", UIControlState.Normal);
button.addOnTouchUpInsideListener(new OnTouchUpInsideListener() {
@Override public void onTouchUpInside(UIControl control, UIEvent event) { run();}
});
setView(button);
}

@Override
public void viewWillAppear(boolean animated) {
super.viewDidAppear(animated);
UIBarButtonItem button = new UIBarButtonItem(UIBarButtonSystemItem.Bookmarks, new OnClickListener() {
@Override public void onClick(UIBarButtonItem barButtonItem) { run();};
});

NSArray items = new NSArray(button);
getNavigationItem().setRightBarButtonItems(items);
getNavigationItem().setTitle("Welcome");
}

protected void run() {
RoboRootViewController gameViewController = new RoboRootViewController();
gameViewController.run(new GameDemo(new Exit() {
@Override public void exit() { getNavigationController().popViewController(true);}
}));
getNavigationController().pushViewController(gameViewController, true);
}

}

public static class GameDemo extends Game.Default {
public static interface Exit {
public void exit();
}

final private Exit service;

public GameDemo() {
this(null);
}

public GameDemo(Exit service) {
super(25);
this.service = service;
}

@Override
public void init() {
CanvasImage image = PlayN.graphics().createImage(100, 100);
image.canvas().setFillColor(Color.rgb(255, 0, 0));
image.canvas().fillRect(0, 0, image.width(), image.height());
ImageLayer imageLayer = PlayN.graphics().createImageLayer(image);
imageLayer.addListener(new Pointer.Adapter() {
@Override
public void onPointerEnd(Event event) {
if (service != null) service.exit();
}
});
PlayN.graphics().rootLayer().addAt(imageLayer, 50, 50);
}
}
}