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<UIBarButtonItem> items = new NSArray<UIBarButtonItem>(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);
		}
	}
}