Using the NativeMaps ANE with Starling/Feathers

We generally use Starling & Feathers to build most of our iOS and Android apps these days. The performance of Starling is great, and while Feathers is mostly aimed at game development, it's an awesome framework for building regular apps as well.

Recently we were building an app which also used our NativeMaps native extension (check it out here: labs.distriqt.com/native-extensions)

One issue with this, however, is that because of the way Starling runs on the GPU, it severely affected the interaction and performance of the native maps interface on iOS. (I'm not sure of the effects on Android, but we used the same technique here across platforms.)

This post is a rough guide to the way we worked around the problem in order to get better performance from the map UI.

There is a good post on the subject here, which was the starting point for our solution and is worth a read: http://forum.starling-framework.org/topic/how-to-pause-starling

What we need to accomplish is to pause the render loop in Starling when the Native Map interface needs to be active. If your map object is full-screen, this is easy and you can simply pause and start Starling when the map is shown or hidden. However it's much more likely that you will have other UI elements apart from the map which need to work as well (such as buttons, navigation etc).

One thing to note is that your other UI elements will still be visible and respond to touch events - but any visual changes such as hover/press states will not be shown since Starling is not rendering and updating the view.

Our solution here was a two-step process.

1. Customise Starling with some additional properties

Firstly, we need to modify the Starling class and add some functionality. Note that you will need to download the source files of Starling to be used in your project rather than the SWC file.

I'm not going to go through this in great detail, so you can download our custom version of Starling from here: Starling.as

A summary of the changes:

  • Added public property pauseMode (boolean)
  • Added public property ignorePause (boolean)
  • Added public method setIgnorePauseFalse to simply change the value of the ignorePause property
  • Modified the render method to check the new properties and decide whether to run it's regular render loop or not

I know, I know, those properties shouldn't really be public but we were in a hurry!

Now, we can set the pauseMode of Starling on or off when we want to display the map.

  1.  
  2. // When the map is created:
  3. Starling.current.pauseMode = true;
  4.  
  5. // When your map is destroyed:
  6. Starling.current.pauseMode = false;
  7.  

This is pretty much all you need to do to get the map to perform properly under Starling, so if your application doesn't have any other UI when the map is visible, you can stop here and not worry about the rest!

2. Making Starling render UI changes when necessary

I assume most people will want their application UI to still update and function while the map is being used. Our solution here was to implement a little more logic to respond to any touch events on relevant UI components and tell Starling to ignore the pauseMode for a short time, forcing a few quick render updates while the UI changes were applied and redrawn.

We created a little helper class for this, called StarlingTouchUtil.as which you can download from here: StarlingTouchUtil.as

The usage for this is as follows:

  1.  
  2. // Assume "_myButton" is a Feathers Button instance or something similar.
  3. // When the map is shown or the view is created:
  4. StarlingTouchUtil.enableTouchRender( _myButton );
  5.  
  6. // When your view is destroyed or you are finished with this button:
  7. StarlingTouchUtil.disableTouchRender( _myButton );
  8.  

That's all there is to it. Please note that this hasn't been thoroughly tested, but this solution worked well enough for our Feathers app.

One more thing to be aware of - if you open the StarlingTouchUtil.as class, you will see it's set up to reset the ignorePause back to false after 300ms. This was suitable for us, but if you have UI component animations or transitions which take longer than 300ms, you'll want to change this value to make sure your visual changes finish before Starling stops rendering again.

3 thoughts on “Using the NativeMaps ANE with Starling/Feathers”

  1. I found it sufficient to lower the frame rate to 1 by setting Starling.current.nativeStage.frameRate=1 while the map is being shown. It would be useful if the NativeMaps would support focusIn and focusOut events to make switching frame rate more easy.

    1. No unfortunately this isn’t possible. The AIR layer sits below the native map layer so all content will be behind the map.

Leave a Reply

Your email address will not be published. Required fields are marked *