threerings/playn — pull request #67 by tomfisher (2014-12-03 11:46:01+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.

package tripleplay.demo;

import org.robovm.apple.foundation.NSArray;
import org.robovm.apple.foundation.NSAutoreleasePool;
import org.robovm.apple.uikit.UIApplication;
import org.robovm.apple.uikit.UIApplicationDelegateAdapter;
import org.robovm.apple.uikit.UIApplicationLaunchOptions;
import org.robovm.apple.uikit.UIBarButtonItem;
import org.robovm.apple.uikit.UIBarButtonItem.OnClickListener;
import org.robovm.apple.uikit.UIBarButtonSystemItem;
import org.robovm.apple.uikit.UIButton;
import org.robovm.apple.uikit.UIControl;
import org.robovm.apple.uikit.UIControl.OnTouchUpInsideListener;
import org.robovm.apple.uikit.UIControlState;
import org.robovm.apple.uikit.UIEvent;
import org.robovm.apple.uikit.UINavigationController;
import org.robovm.apple.uikit.UIScreen;
import org.robovm.apple.uikit.UIViewController;
import org.robovm.apple.uikit.UIWindow;

import playn.core.CanvasImage;
import playn.core.Color;
import playn.core.Game;
import playn.core.ImageLayer;
import playn.core.PlayN;
import playn.core.Pointer;
import playn.core.Pointer.Event;
import playn.robovm.RoboRootViewController;
import tripleplay.demo.Main.GameDemo.Exit;

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);
}
}
}