iOS Backend

Overview

iOS is an operating system that expects strict control over its apps, enforcing an application life cycle along with stringent memory and performance requirements. In a traditional desktop operating system, an application is free to have its own event loop and use as many resources as it pleases, while an application on iOS can expect to be terminated if control is not handed back to the operating system in a certain amount of time or begins monopolizing memory that is needed by. Additionally, apps on iOS can be killed at any time by the operating system if it determines more memory is needed for another app. This makes it important to be able to quickly save and restore application state based on pause and resume events, something that Panda has not had to concern itself with up to this point.

Because there are long-term plans for deprecating ShowBase and PandaFramework in lieu of a unified application framework, it would be preferable to come up with a design that will work with all of these. The design should also be able to be applied to Android as much as possible.

Implementation

PandaViewController

PandaViewController will encapsulate the entire Panda lifecycle (similar to PandaActivity on Android). The documentation for UIViewController can be found here. In the simplest app, PandaViewController will take up the entire screen and will be the only view controller. This is not strictly necessary, however. For example, there could be a “Panda3D Samples” app that displays a list of all the engine samples in a native table view, and allows each one to be started and stopped at will. And because PandaViewController encompasses all of Panda, nothing outside of the view controller needs to know about Panda’s existence.

The life cycle of a PandaViewController will look something like this:
  • Specify the path to an embedded Python module containing a Panda app (or for a C++ app, a pointer to the application’s main function), and optionally, a PRC file.
  • Register the app's main thread with Panda, since it won’t know about it by default.
  • Create a new NSThread that executes the specified Python module or C++ function.
  • Poll GraphicsEngine until a window has been created. The GraphicsWindow will have a UIView reference that is set up to render Panda’s OpenGL context. Attach this view to the view controller.
  • Set up app life cycle event hooks with Panda’s EventHandler. These will be events like app-pause, app-resume, app-memory-warning.
  • While the user is interacting with the app, the view controller will send touch, gesture, and resize events to the GraphicsWindow or other appropriate objects.
  • When the view controller leaves the screen, it will tear down Panda and destroy/deallocate any extra references.

Touch Input

By default, touch inputs will be translated into mouse events, which can be deactivated with a PRC variable. Features like multi-touch will be disabled in this state.

Building and Distribution

FreezeTool can be extended to support creating iOS application bundles. In order for these apps to be easily be runnable on a physical device, a skeleton Xcode project will need to be created, since the Xcode UI is the only way you can quickly install and run apps on-device.

I don’t know if Panda’s setuptools scripts are meant to be used for day-to-day debugging, so we could potentially create a separate script that would handle creating a debug build of the app along with the Xcode project. As much of the build infrastructure as possible would go into FreezeTool, though.

Checklist

  • Read .prc files from the app bundle
  • Investigate why shaders seem to be broken
  • It’s because the shader generator doesn’t support GLSL. Should probably hold off since a shader overhaul is in the works.
  • Mouse emulation
  • PRC option
  • Multi-touch support
  • multitouch branch: Replace x and y doubles with LPoint3
  • Touch trackball controls
  • C++ app support
  • Rudimentary way of handling high-dpi displays