Archive for July, 2007

Embedding fonts in Flash CS3/AS3

July 29, 2007

package
{
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.Font;
import flash.utils.getDefinitionByName;

    public class SimpleTextPaneTestDrive01 extends Sprite
{
private static var embeddedFont:Font = null;

        //CONSTRUCTOR
public function SimpleTextPaneTestDrive01()
{
var embeddedFontClass:Class = getDefinitionByName(“Font1”) as Class;
Font.registerFont(embeddedFontClass);
var embeddedFontsArray:Array = Font.enumerateFonts(false);
embeddedFont = embeddedFontsArray[0];
var fmt:TextFormat = new TextFormat();
//fmt.bold = true;
fmt.color =0xffffff;
fmt.size = 16;//Old day fashion: If you embed it in a textfield on stage
//fmt.font = “Helvetica”;
fmt.font = embeddedFont.fontName;

            var tf:TextField = new TextField();
tf.text = “hello world!”;

tf.setTextFormat(fmt);

}

}
}

Links:

Loading fonts at runtime
Using hasGlyphs() with embedded fonts

Advertisements

Understanding Polymorphism 101

July 27, 2007

Polymorphism is all about “interchangeable” objects. According to Thinking in Java (2nd ed):

When dealing with type hierarchies, you often want to treat an object not as the specific type that it is, but instead as its base type. This allows you to write code that doesn’t depend on specific types.

1. Set type to interface instead of an abstract/concrete class is considered a better OO approach. A fancy way of rephrasing this is to program to interfaces instead of concrete implementations. Other approaches include inheritance and composition.

var reader:IReader = new FileReader(url);

In the preceding code, we set type of reader to its interface IReader instead of its own type FileReader. This way we “program to the interface”.

2. Interfaces can extend other interfaces (but not abstract or concrete classes). All the classes that implement an interface should also implement all the interfaces the interface extends. A convenient way of implementing an interface is to extend an abstract/concrete class that already implements it. Example:

package test
{
import flash.events.IEventDispatcher;
public interface IReader extends IEventDispatcher{}
}

package test
{
import flash.events.EventDispatcher;
import test.IReader;
public class AbstractReader extends EventDispatcher implements IReader
{
public function read():void
{
trace("i am reading!");
}
}
}

AMFPHP with ActionScript 3 101

July 20, 2007

Client-side:

1. Use flash.net.NetConnection to call server-side function this way:

var conn:NetConnection = new Connection();

conn.connect(http://www.mysite.com/amfphpgatewaydir/gateway.php);

conn.call(“com.projectA.ClassName.getCash”, new Responder(onResult, onFault), param1, param2);

In the call() function of Connection object, the first parameter is the method “identifier” of type String in the form of dot-delimited packagePath.className.methodName; the second parameter is a Responder object that takes two parameters with the first one onResult handler and the second one onFault handler (both takes one paramter of tyep Object); the rest/consecutive parameters are the parameters that are taken by the first remote method call.

2. Implement onFault() and onResult() for the remote method call. onFault() always take a type Object parameter against which you can still reflect by the old-good-day “for-property-in-object” style loop. onResult() takes the returned function call result from the remote method. It can be complex type such as Object or native AS3 dataTypes such as String or Array. A server-side defined class needs to have its corresponding AS class and is deserialized as “associative” array by onResult().

Below is a snippet AS of working example:


package test
{
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.system.System;
import flash.net.NetConnection;
import flash.net.ObjectEncoding;
import flash.net.Responder;
import flash.utils.describeType;
import packageName.ClassName;
public class AMFPHPTest01 extends Sprite
{
private var _foo:TextField;
private var gatewayURL:String = "http://www.mysite.com/amfphpservice/gateway.php";
private var connection:NetConnection;
public function AMFPHPTest01():void
{
inititialize();
}
private function inititialize():void
{
_foo = new TextField();
_foo.text ="info";
_foo.autoSize = TextFieldAutoSize.LEFT;
addChild(_foo);
//
init();
}
private function init():void
{
_foo.text = "TotalMemory: "+System.totalMemory;
connection = new NetConnection();
//connection.objectEncoding = ObjectEncoding.AMF0;
connection.connect(gatewayURL);
connection.call("packageName.className.methodName", new Responder(onResult, onFault), 1);
}
private function onResult(evt:Object):void
{
_foo.text = "onResult!";
reflect(evt);
}
private function onFault(obj:Object):void
{
_foo.text = "onFault!\n"+"obj: "+obj.error;
reflect(obj);
/*
description: The class {*} could not be found under the class path {*}
level: User Error
details: */BasicActions.php
code: AMFPHP_FILE_NOT_FOUND
line: 33
*/
var description:XML = describeType(obj)
//will output an xml object
trace(description..accessor.@name.toXMLString());
}
private function reflect(obj:Object)
{
for(var i in obj)
{
_foo.appendText("\n"+i+": "+obj[i]);
//trace(i+": "+obj[i]);
}
}
}
}

Server-side:

1. No need to define a method table to expose services to the gateway any more. Just declare those methods as public;

2. Use _explicitType as a class member to map a php class to an AS one like this in a php class definition.

"var $_explicitType = "packageName.ClassName“;

Reflection in AS3

July 17, 2007

1. Use flash.utils.describeType function to get properties of an object

import flash.utils.describeType;
var description:XML = describeType(v3dView)
//will output an xml object
trace(description..accessor.@name.toXMLString());

2. Use the old-good-day “for-property-in-object” loop to get properties/values of an object

3. Use is/as/instanceof operands to determine whether an object is compatible to or a member of the data type:

//output true
trace("is pp type of AccountProxy? "+(pp is AccountProxy));

//output [object AccountProxy]
trace("is pp as AccountProxy? "+(pp as AccountProxy));

//output true
trace("is pp instance of AccountProxy? "+(pp instanceof AccountProxy));

Declaring stage instances from Library

July 17, 2007

1. Uncheck “Publish settings->AS3->Automatically declare stage instances”;

2. Right click Sprite/MovieClip in Library. Check “Linkage”, assign”Class”and “Base class”. I think the base class is either “Sprite” or “MovieClip”;

3. Declare instance as a property of the Document class. The class must be declared as public in order not to get a compiler error. Like so:

public var bkgdrop:Backdrop;

or

public var bkgdrop:Sprite;

Links:

Class path / Document class

July 16, 2007

It took me like 10 minutes to figure out…

The class path, if under the directory “Classes” which is inside the same directory as the running .fla, should be:

./Classes

Not:

Classes

Nor:

/Classes

Document class (accessed by right-click on stage) is dot name-spaced.

Garbage collection in FP(AS3)

July 15, 2007

1. To remove an object (to authorize Flash Player to garbage collect it in the next GC cycle), simply remove the references to the object by doing so:

var fruit:Fruit= new Apple();
fruit = null;

or reuse the reference and stuff it with another object, like so:

fruit = new Orange();

2. Since garbage collection of a large amount of objects will be a big performance hit, rule of thumb is, you should strive to reuse rather than to delete an object for GC whenever possible.

3. When the programmer authorizes FP to garbage collect an object, he should always remember the followings:

  • Remove all the event listeners of the target before removing it;
  • Remove all the intervals, timers (Timer/timeout) that are associated with the object;
  • Remove all the timeline functions within the instances of DisplayObject that are associated with the object;
  • Remove all the tween instances and onEnterFrame handlers that are associated with it.
  • URLLoader is also on the blacklist as some people noticed.

Example:

Before refactoring:
public function set tweenPosX(v:Number):void
{
//var duration:Number = UNIT_DIST_DURATION*Math.abs(v-posY);
var duration:Number = .5;
//if(duration==0)return;
var tween:Tween = new Tween(this, "posX", Regular.easeInOut, posX, v, duration, true);
tween.addEventListener(TweenEvent.MOTION_FINISH, tweenPosXFinish);
}

The code above is problematic since tween is a local variable and it registers function tweenPosXFinish() within the setter function. When the setter function finishes execution, tween is disposed of for GC while its TweenEvent listener is not. The listener object will take up more and more memory as consecutive calls to the setter function until the next mark/sweep GC process occurs. both tween and its listener function remain in memory; all the instances get stacked with sequential tweening until the next Mark/Sweep process occurs. The app takes up around 6mb (“6,569,984”) memory in standalone player and continues to take up more memory with sequential calls to the setter/tweening function until it reaches around 8mb(“7,909,376”, etc.); In a fresh web browser (without other tabs/windows open), it starts taking around 2mb (“2,093,056”) with similar situation until the memory usage reaches around 3mb (“3,133,440”). GC doesn’t seem to be able to get rid of the local references to a tween instance. I came up with this conclusion because using weak references to the listeners of the tween didn’t solve the issue; so it presumably was not listener issue.

After refactoring: tween_posX becomes instance variable and GC is reused.

private var tween_posX:fl.transitions.Tween;
public function set tweenPosX(v:Number):void
{
//var duration:Number = UNIT_DIST_DURATION*Math.abs(v-posY);
var duration:Number = .5;
tween_posX = new Tween(this, "posX", Regular.easeInOut, posX, v, duration, true);
tween_posX.addEventListener(TweenEvent.MOTION_FINISH, tweenPosXFinish);
}

Links:

Kirupa: ActionScript 3 Tip of the day Page 9

gskinner: Weakly referenced listeners

[Added Sept 03, 07]

Someone on FlashMedia maillist had this one:
Never Ever Use Tween or URLLoader or Loader or Timer or…

Getting mouse coordinates on stage

July 14, 2007

In ActionScript 3.0, displayObject instances have mouseX/mouseY properties; MouseEvent instance have localX/localY properties and stageX/stageY properties.

If there are other displayObject instances on stage and when cursor rolls over any of them, mouseX/mouseY becomes relative to that instance as opposed to relative to stage. To get the mouse coordinates relative to the stage, use stageX/stageY properties.

Or use localToGlobal method of displayObject class. Like this:

import flash.events.MouseEvent;
import flash.text.TextField;
import flash.geom.Point;
//var _foo:TextField;
function onMouseMove(evt:MouseEvent){
//trace(evt.target.mouseY);
var target:* = evt.target;
//_foo.text = target.mouseY;
//_foo.text = evt.localY.toString();

var location:Point = new Point(target.mouseX, target.mouseY);
location = target.localToGlobal(location);
_foo.text = target.mouseY + ": "+ location.y;}

//root.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);

eveyday unicode characters in web design

July 14, 2007

» & raquo;
& #149;
•  & #8226;
& & amp;
non-break space & nbsp;
en-dash/– & ndash;
em-dash/— & mdash;
Opening Double Quotes & ldquo;
Closing Double Quotes & rdquo;

Sources:

Unicode character finder

HTML accent entity codes

“Differentiating between Type and Class”

July 4, 2007

var item:Vegetable;“”To write more flexible code, you have to differentiate between class and type. In the preceding example, Vegetable is both a class and the type. However, there is a correspondence between a type and an interface and between a (concrete) class and an implementation. Although a concrete class defines both an interface and implementation, an interface defines just the interface. Likewise, a class is also a type, but a type does not have to be a class. Types can also be interfaces. By declaring variables with interface types, you create greater flexibility in your code. Consider the following example:”var item:IProduce;

Wow, It is so deep. I am already on page 39 of ActionScript 3 with Design Patterns” by Lott and Patterson. Hopefully could get it done by the end of the summer!;)