Date.time vs. Date.setTime() getTime() performance

Using Date.setTime() and Date.getTime() is faster than Date.time.

My quick speed test to determine the fastest way to get and set time values on Date objects:

var date : Date = new Date();
var max : Number = date.time;
 
var start : int;
var end : int;
var time : Number;
var times : Vector.<Number> = new Vector.<Number>(); 
 
var c : int = 1000000;
for ( var i : int = 0; i < c; i++ ) { times.push( Math.round( max * Math.random() ) ); }
 
start = getTimer();
for ( i = 0; i < c; i++ ) { date.time = times[ i ]; };
end = getTimer();
trace( "date.time = times[ i ];", end - start );
 
start = getTimer();
for ( i = 0; i < c; i++ ) { date.setTime( times[ i ] ); };
end = getTimer();
trace( "date.setTime( times[ i ] );", end - start );
 
start = getTimer();
for ( i = 0; i < c; i++ ) { time = date.time; };
end = getTimer();
trace( "time = date.time;", end - start );
 
start = getTimer();
for ( i = 0; i < c; i++ ) { time = date.getTime(); };
end = getTimer();
trace( "time = date.getTime();", end - start );
 
// Result:
//
// date.time = times[ i ];		381
// date.setTime( times[ i ] );	270
// time = date.time;			184
// time = date.getTime();		65

Flash iOS packager update released!

Everything New in Adobe AIR 2.6 (read all on Christian Cantrells blog):

  • Asynchronous Bitmap Decoding
  • Owned Windows
  • Bitmap Capture in StageWebView
  • Microphone support on iOS
  • StageWebView on iOS
  • Multitasking on iOS
  • Retina Support on iOS
  • iOS Camera, CameraUI, and CameraRoll Support
  • Improved hardware acceleration on iOS
  • PFI is now ADT
  • Configurable panning with soft keyboard activation
  • Programmatic control of the display of the on-screen keyboard
  • Support for the Amazon Android Market (more info)
  • Vector printing on Linux
  • Native cursor support
  • On-device debugging over USB (Android only)
  • Native Menu event refinement
  • Enhanced text support on Android
  • NetConnection.httpIdleTimeout
  • Bundled Android USB drivers on Windows
  • Support for the vipaccess:// URI
  • -version flag for ADT

Get runtime and get SDK.

Video – developing for iOS with AIR for mobile 2.6/

The Hitchhiker’s Guide to a Flash Player update

I really hate Flash Player updates just because it always takes me some time to figure out again how to update all of them on my Mac. Why isn’t there some kind of centralized Flash Player Manager?

Well, as normal user it’s really easy. Just visit Adobe and you’re almost done. But for me as developer I need to update all players used by Flash CS 5, Flash Builder 4 and the Flex SDKs as well. Note to myself: Just remember these steps (in this case for 10.2):

Visit the Flash Player Download Heaven.

Update Browser Debug Player:

  • “Download the Macintosh Flash Player X.X Plugin content debugger (Intel-based Macs)”
  • Run “Install Adobe Flash Player Debugger.app”.
  • Do nothing with Google Chrome! It updates automatically and will be your performance weapon of choice. It’s still running a release version of Flash Player. Really great if you use apps like http://audiotool.com/.

Update Adobe Flash CS 5 Release Projector for Mac OS X:

  • “Download the Macintosh Flash Player 10.2 Projector”
  • Save file as Applications/Adobe Flash CS 5/Players/Flash Player.app

Update Adobe Flash CS 5 Debug Projector for Mac OS X:

  • “Download the Macintosh Flash Player 10.2 Projector content debugger”
  • Save file as Applications/Adobe Flash CS 5/Players/Debug/Flash Player Debugger.app

Update Adobe Flash CS 5 Release Projector for Windows:

  • “Download the Windows Flash Player 10.2 Projector”
  • Save file as Applications/Adobe Flash CS 5/Players/FlashPlayer.exe

Update Adobe Flash CS 5 Debug Projector for Windows:

  • “Download the Windows Flash Player 10.2 Projector content debugger”
  • Save file as Applications/Adobe Flash CS 5/Players/Debug/FlashPlayerDebugger.exe

Well, there is one issue I don’t understand, but I think everything is working properly. I created a little file running this script:

import flash.system.Capabilities;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
 
var textField : TextField = new TextField();
	textField.autoSize = TextFieldAutoSize.LEFT;
	textField.text = Capabilities.version;
 
addChild( textField );

But when I’m just “testing” in Flash CS 5 it still says “MAC 10,1,52,14”. When I’m “debugging” it says “MAC 10,2,152,26”. I removed all Flash Player.app and Flash Player Debugger.app except the latest. If you have a clue – let me know.

Just for me – Flash Player Updates I manually installed lately:

  • 15.06.2011 – MAC 10,3,181,26

Set WP-Syntax tab width

Since I’m using the WP-Syntax plug-in on my blog I tried to optimize font size and the tab width. Like a lot of developers I heavily use tabs in my source code. These tabs are really wide within the browser so I was looking for a way to minimize the used space.

I’m not a CSS guy but it seems like there is no way to set a specific tab width. So why not replace the tab with white space?

My change to wp-syntax/wp-syntax.php:

function wp_syntax_highlight($match)
{
    global $wp_syntax_matches;
 
    $i = intval($match[1]);
    $match = $wp_syntax_matches[$i];
 
    $language = strtolower(trim($match[1]));
    $line = trim($match[2]);
    $escaped = trim($match[3]);
    $code = wp_syntax_code_trim($match[4]);
 
    // INSERT JUST THIS LINE OF CODE
    $code = str_replace ( '\t' , '   ' , $code );
    .
    .
    .

Flex 4 DragManager.doDrag() with .acceptDragDrop() error

While diving into the Flex 4 spark framework I ran into a problem using

mx.managers.DragManager.doDrag() with
mx.managers.DragManager.acceptDragDrop():

If you just drag, accept on dragDrop and then drop without moving the mouse you’ll get this error:

TypeError: Error #1009:
at mx.managers.dragClasses::DragProxy/mouseUpHandler()
[E:\dev\4…\mx\managers\dragClasses\DragProxy.as:591]

This is, because DragProxy didn’t receive a MouseEvent yet. So what you can do is manually send one. See this little use case and test for yourself:

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx"
 
			applicationComplete="construct()"
			height="100%"
			width="100%">
	<fx:Script>
		<![CDATA[
			import mx.controls.Alert;
			import mx.core.DragSource;
			import mx.core.UIComponent;
			import mx.managers.DragManager;
 
			private function construct() : void
			{
				// Get notified whan a global error occurs
				loaderInfo.uncaughtErrorEvents.addEventListener( UncaughtErrorEvent.UNCAUGHT_ERROR, errorHandler );
			}
 
			private function onButtonMouseDown( event : MouseEvent ) : void
			{
				var button : UIComponent = UIComponent( event.target );
				var dragSource:DragSource = new DragSource();
 
				DragManager.doDrag( button, dragSource, event );
 
				// Accept dragDrop
				if ( acceptDragDropCheckBox.selected )
				{
					DragManager.acceptDragDrop( this );
				}
 
				// Avoid error
				if ( avoidErrorCheckBox.selected )
				{
					button.dispatchEvent( new MouseEvent( MouseEvent.MOUSE_MOVE, true,false, button.mouseX, button.mouseY ) );
				}
			}
 
			protected function errorHandler( e : UncaughtErrorEvent ) : void
			{
				Alert.show("An error has occurred and been caught by the global error handler: " + String( e.error ), "My Global Error Handler");
				e.preventDefault();
			}
		]]>
	</fx:Script>
	<s:Label x="20" y="10" text="If you accept dragDrop you need to avoid the error!"/>
	<s:CheckBox id="acceptDragDropCheckBox" x="20" y="30" label="Accept DragDrop"/>
	<s:CheckBox id="avoidErrorCheckBox" x="20" y="50" label="Avoid error"/>
	<mx:Button id="dragButton" x="20" y="110" mouseDown="onButtonMouseDown(event)" label="Drag me. Or click me for error!"/>  
</s:Application>

UPDATE:

A much better way to avoid this error is listening to a DragEvent.DRAG_ENTER before calling DragManager.acceptDragDrop():

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx"
 
			dragEnter="dragEnterDataRenderer(event)"
 
			height="100%"
			width="100%">
	<fx:Script>
		<![CDATA[
			import mx.core.DragSource;
			import mx.core.UIComponent;
			import mx.events.DragEvent;
			import mx.managers.DragManager;
 
			private function onButtonMouseDown( event : MouseEvent ) : void
			{
				var button : UIComponent = UIComponent( event.target );
				var dragSource:DragSource = new DragSource();
 
				DragManager.doDrag( button, dragSource, event );
			}
 
			private function dragEnterDataRenderer( event : DragEvent ) : void
			{
				DragManager.acceptDragDrop( this );
			}
		]]>
	</fx:Script>
	<mx:Button id="dragButton" x="20" y="20" mouseDown="onButtonMouseDown(event)" label="Click me. Drag me. No Error."/>  
</s:Application>

Amazing Math Tutorial Video Site

I really need to quote this bit-101 blog post.
It’s the first time I heard about that great website:

http://www.khanacademy.org/

I don’t have much more to say about this. Do you need to learn or brush up on any subject related to math? You will find a wealth of data here in a massive number of videos, each 10 minutes or under. Seriously, anything you want to learn is here, from the basics to advanced calculus. Where does this guy find the time?

I got the link from Brook Andrus’ site, where she gives a bit more info on the author. Pretty amazing guy.

http://www.brooksandrus.com/blog/2010/10/01/the-wrath-of-khan-the-genesis-of-21st-century-education

UPDATE: There’s another one: http://patrickjmt.com/

Linked List Performance Test

I was thinking about not creating linked lists for every data type I use but using one abstract data structure containing my specific data types.

So I wrote this short performance check:

package de.superclass 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import flash.utils.getTimer;
 
	public final class LinkedListTest extends Sprite 
	{
		private var _abstractItemLinkedList : AbstractItem;
		private var _dataItemLinkedList : DataItem;
		private var _vector : Vector.<DataItem>;
 
		public function LinkedListTest()
		{
			loaderInfo.addEventListener( Event.COMPLETE, onLoaderInfoComplete );
		}
 
		private function onLoaderInfoComplete( event : Event ) : void 
		{
			createData( );
 
			var timer : Timer = new Timer( 3000, 1 );
				timer.addEventListener( TimerEvent.TIMER_COMPLETE, onTimerComplete );
				timer.start();
		}
 
		private function onTimerComplete(event : TimerEvent) : void 
		{
			runTest( );
		}
 
		private function createData() : void 
		{
			var vector : Vector.<DataItem> = _vector = new Vector.<DataItem>();
			for ( var i : int = 0; i < 5000000; i++ )
			{
				var dataItem : DataItem = new DataItem();
					dataItem.index = i;
 
				vector.push( dataItem );
 
				var abstractItem : AbstractItem = new AbstractItem();
					abstractItem.data = dataItem;
 
				if ( i == 0 )
				{
					_dataItemLinkedList = dataItem;
					_abstractItemLinkedList = abstractItem;
				}
				else
				{
					previousDataItem.next = dataItem;
					previousAbstractItem.next = abstractItem;
				}
 
				var previousDataItem : DataItem = dataItem;
				var previousAbstractItem : AbstractItem = abstractItem;
			}
		}
 
		private function runTest() : void 
		{
			var dataItem : DataItem;
			var startTime : int;
 
			var vector : Vector.<DataItem> = _vector;
			var c : int = vector.length;
 
			startTime = getTimer();
			for ( var i : int = 0; i < c; i++ )
			{
				dataItem = vector[ i ];
				dataItem.index = dataItem.index;
			}
 
			var durationVector : int = getTimer() - startTime;
 
			startTime = getTimer();
			dataItem = _dataItemLinkedList;
			while ( dataItem )
			{
				dataItem.index = dataItem.index;
				dataItem = dataItem.next;
			}
 
			var durationDataItemLinkedList : int = getTimer() - startTime;
 
			startTime = getTimer( );
			var abstractItem : AbstractItem = _abstractItemLinkedList;
			while ( abstractItem )
			{
				dataItem = abstractItem.data;
				dataItem.index = dataItem.index;
				abstractItem = abstractItem.next;
			}
 
			var durationAbstractItemLinkedList : int = getTimer() - startTime;
 
			startTime = getTimer( );
			abstractItem = _abstractItemLinkedList;
			while ( abstractItem )
			{
				dataItem = DataItem( abstractItem.data );
				dataItem.index = dataItem.index;
				abstractItem = abstractItem.next;
			}
 
			var durationAbstractItemLinkedListWithCast : int = getTimer() - startTime;
 
			startTime = getTimer( );
			abstractItem = _abstractItemLinkedList;
			while ( abstractItem )
			{
				dataItem = abstractItem.data as DataItem;
				dataItem.index = dataItem.index;
				abstractItem = abstractItem.next;
			}
 
			var durationAbstractItemLinkedListWithAs : int = getTimer() - startTime;
 
			trace( "Durations:" );
			trace( "Vector", durationVector );
			trace( "DataItem LinkedList", durationDataItemLinkedList );
			trace( "AbstractItem LinkedList", durationAbstractItemLinkedList );
			trace( "AbstractItemLinkedList Using Cast", durationAbstractItemLinkedListWithCast );
			trace( "AbstractItemLinkedList Using As", durationAbstractItemLinkedListWithAs );
		}
	}
 
}
 
class AbstractItem
{
	public var data : *;
	public var next : AbstractItem;
}
 
class DataItem
{
	public var index : int;
	public var next : DataItem;
}

Results on my MacBook Pro i7:

Durations:
Vector 91
DataItem LinkedList 53
AbstractItem LinkedList 76
AbstractItemLinkedList Using Cast 108
AbstractItemLinkedList Using As 121

Alsways use explicit implemented linked lists!

Flash on iOS issue with flash.net.navigateToUrl( );

I’m playing around with Flash packager for iPad and iPhone and it seems like there might be some restrictions on accessing files bundled with the application and delivered within the application directory.

During some video tests I delivered one h.264 video within the application directory and tried starting it using this code invoked on a MouseDown event:

var file : File = File.applicationDirectory.resolvePath( "video.mp4" );
navigateToURL( new URLRequest( file.url ) );

But nothing happened. Really nothing. No thrown error. It’s like I simply didn’t call navigateToUrl. Of course everything works fine with remote URLs so I’m quite sure I didn’t make a mistake.

After several different approaches I figured out I couldn’t access any of my files within the app:/ directory. Regardless of the filetype. Well, at least it didn’t work on my devices: iPhone with iOS 4.1 and iPad with iOS 3.2.2.

There’s a discussion about that the Adobe forums: http://forums.adobe.com/message/2979185

iPhone / iPad ActionScript Guide quotes

As I mentioned here I strongly recommend to read Adobe’s Building ADOBE® AIR® Applications with the Packager for iPhone® guide or Flash Platform for iPhone.

Just some ActionScript facts:

ActionScript APIs unsupported on mobile devices
ActionScript APIs specific to mobile AIR applications
ActionScript APIs of special interest to mobile application developers

iPhone / iPad Development Guide quotes

Since I’m diving deeper into Flash for iOS devices I strongly recommend to read Adobe’s Building ADOBE® AIR® Applications with the Packager for iPhone® guide or Flash Platform for iPhone.

Beside the know how of subscribing as a Apple developer, obtaining certificates and so on I think this informations are quite valuable but easy to forget:

iPhone icon and initial screen images

The iPhone adds a glare effect to the icon… To remove this default glare effect, add the UIPrerenderedIcon key to the InfoAdditions element in the application descriptor file…

All iPhone applications display an initial image while the application loads on the iPhone. You define the initial image in a PNG file named Default.png stored in the main development directory… The Default.png file is 320 pixels wide by 480 pixels tall, regardless of the initial orientation of the application or whether it is full-screen or not.

The iPhone displays its status bar over the 20 pixel-wide rectangle at the top or left of the default image.

For iPad support, you can define images for each supported initial orientation (Default-Portrait, Default-PortraitUpsideDown, Default-LandscapeLeft, Default-LandscapeRight.png)… Initial screen images for the iPad are 768 pixels wide and 1024 pixels high.

iPhone application settings

There must be way more settings than this:

<iPhone><InfoAdditions><![CDATA[
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleBlackOpaque</string>
<key>UIRequiresPersistentWiFi</key>
<string>NO</string>
]]></InfoAdditions></iPhone>

Debugging an iPhone application

Debugging the iPhone App over Wi-Fi is possible and GPU rendering diagnostics can be activated at compile time.

Continue reading about more specific ActionScript notes here.