Tag Archives: actionscript

Lazy Loading of Proxies

While working on a pureMVC project, I realised that there were N number of proxies registered with facade (yes, ApplicationFacade). The truth was, not all have been used during life cycle of a typical user functionality.

So what? It was merely difficult to categories the proxies for need of individual module/functionality.

The simple idea is to implement Lazy Loading / Lazy registration of proxy!

Instead of declaring statement at compile time like

facade.registerProxy(new MyProxy()); 

I overridden

retrieveProxy(...)

function in extended Facade class:

override public function retrieveProxy(proxyName:String):IProxy
{
 var proxyInstance:IProxy = super.retrieveProxy(proxyName);
 if(proxyInstance==null)
 {
 var myClass:Class = getDefinitionByName(proxyName) as Class;
 if(!myClass)
 return null;

 var proxyInstance:IProxy = new myClass();
 if(proxyInstance)
 registerProxy(proxyInstance);
 }
 return proxyInstance;
}

This also takes care of not registering duplicate proxy.
Uh oh! While doing this trick, I encountered on more problem.


ReferenceError: Error #1065: Variable myClass is not defined.

I banged my head and tried to figure out the reason. After digging for some time, I found that the (class) definition of proxy was somehow not been retrieved with

getDefinitionByName() 

.
It wasn’t possible to simply add import statements with those Proxy class names as Flex compiler ignores such unused (yes while compiling none of proxy was referenced) imports.

Simple trick worked:
in extended facade class constructer, I declared each proxy as variable, something like:

public class ApplicationFacade extends Facade
{
 public function ApplicationFacade(parameter:SingletonEnforcer)
 {
 super();

 var myProxy:MyProxy;
 }
}

and that’s all I wanted! The trick is this code doesn’t force an instance of proxy to be created, still at runtime when required, it finds definition of MyProxy class.

Adobe Flash Player & KeyboardEvent – FullScreenEvent relation explored

Since Adobe Flash player has allowed limited keyboard support for full screen mode (application), the feature also comes with a strange cost.

When KeyboardEvent.KEY_DOWN event listener is registered on stage, KeyboardEvent with keycode 32 (equivalent to Space key) is fired always when the application goes from normal state to full screen state!

To make sure, I made a sample test application as under:

package 
{
	import flash.display.*;
	import flash.events.*;
	import flash.text.TextField;
	import flash.net.URLRequest;
	import flash.ui.Keyboard;

	public class fullScreenTest extends Sprite
	{
		private var loader:Loader;
		private var player:Object;
		public function fullScreenTest()
		{
			super();
			if(stage)
				onAddedToStage();
			else
				addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
		}
		
		private function onAddedToStage(event:Event = null):void
		{
			if(hasEventListener(Event.ADDED_TO_STAGE))
				removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			var changeScreenState:TextField = new TextField();
			changeScreenState.text = "Change Screen State";
			changeScreenState.selectable = false;
			changeScreenState.addEventListener(MouseEvent.CLICK, onChangeScreenState);
			addChild(changeScreenState);
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			stage.addEventListener(FullScreenEvent.FULL_SCREEN, onToggleFullScreen);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
		}
		
		private function onChangeScreenState(event:Event = null):void
		{
			if(stage.displayState == StageDisplayState.NORMAL)
				stage.displayState = StageDisplayState.FULL_SCREEN;
			else
				stage.displayState = StageDisplayState.NORMAL;
		}
		
		private function onToggleFullScreen(event:FullScreenEvent):void
		{
			trace("is app in full screen? "+event.fullScreen);
		}
		
		private function onKeyDown(event:KeyboardEvent):void
		{
			if(event.keyCode == Keyboard.SPACE)
			{
				trace("event target : " + event.target +
						"\n\tevent keycode : " + event.keyCode);
			}
		}
	}
}

Up to surprise, KeyboardEvent.KEY_UP listener does the same job, perfectly fine, without sending extra KeyboardEvent with SPACE keyCode! Of course, this doesn’t apply when application state changes to normal, from full.

So, in a way the solution to this is either only use KeyboardEvent.KEY_UP event listener(s) or, remove event listener registered with KeyboardEvent.KEY_DOWN while switching from normal screen state of application to full screen, after some dummy time, (re)register listener for KeyboardEvent.KEY_DOWN !

I am yet not sure why FullScreenEvent event comes with KeyboardEvent event instance propagating through!

Flash Player Cache and loading issues

By programming its not possible to clear out flash player and browser cache at a point of time, that too without user’s knowledge.
This, at times creates problem when a third party component, say SWF is loaded. Generally the URL from where SWF is to be loaded remains constant. So Flash Player often caches for browser’s easy experience.

However, if the third party – remote component if again in turn does some activity over network, it gives randomly wrong results  Generally this happens because the loaded component actually resides in cache, at times.

To overcome this, there is a way, not to clear cache, but to make browser and flash player feel as if you are always loading some new component (say SWF) from new location.
This simple trick is achieved by doing something like….
http://haritkothari.wordpress.com/myNewComp.swf?[firstparam=123&secondparam=456]&randomcount=Math.random()*Math.random()

The randomcount query param has no more significance other than make FP feel its another URL request, which is not cached! The stronger you implement dummy param, the less is probable for FP to cache.

This can be easily be used with loader to load remote component, however only care need to take is the dummy parameter should not be such that is interpreted by remote component, otherwise result may go to any extent!!!

This is also not Flash Player or actionscript specific trick, even banking and few other sites implement this in stronger ways to avoid caching, apart from session id!

Flex (Flash Player) – DPI and input/output

DPI is often confused with screen resolution. Actually when screen resolution changes (in pixel height x width) the DPI rate is not necessarily changed.

In most cases DPI remains same, unless changed intentionally. In simple language, increasing screen resolution will allow more dots to be displayed on screen, by decreasing distance between each dot. Increasing DPI rate of screen but keeping resolution will increase number of dots per inch; by decreasing dot thickness, and that will eventually result into more dots in whole screen, with unchanged resolution.

When image resolution comes into picture, DPI plays role to consider depth of an Image. More the DPIs, better is the image – depth.
Two similar looking image (at its original size) may have different DPIs. The image with higher DPI rate, if zoomed in, will not get blurred or distorted very easily.

DPI is the somewhat similar concept of mega pixel – the camera term.

This term and its effect came into picture when I started input and output to real wprld from Flex application!
Flex application (or flash player) accepts width, height, x, y or such dimension properties in pixels only. The real world deals with inch, foot, centimeter or any such unit.

So where the game is?

Above simple question puzzles many.
widthInch = widthPixels/DPI is the key!

Say you have image with 500 pixels, width in inch will be 500/DPI. So if DPI is 96, then width is 500/96inches.

In case of flash player, DPI rate is 96.
So if I want to display an image in 2 inches width, I need to set image width to 2*96 pixels. This ignores Image (physical image file) and its DPI rate as I am going to display in flash player, not any image editor.

Also, this bug post is strange upto my knowledge. Flash Player’s DPI seems constant, ignoring screen DPI.

3 ways to get control in Flex over user input through Keyboard

1. Use of restrict property. The following example allows only numeric input

<mx:TextInput id="textInput" restrict="0-9\-" />

2. Use of unicodeRange style property inside CSS (stylesheet) while embedding fonts. The following example restricts all special symbols except period sign(.).

@font-face
{
src:url("../assets/myFont.ttf");
fontFamily: myFontFamily;
flashType: true;
unicodeRange:
U 0041-U 005A, /* Upper-Case [A..Z] */
U 0061-U 007A, /* Lower-Case a-z */
U 0030-U 0039, /* Numbers [0..9] */
U 002E-U 002E; /* Period [.] */
}

3. Use of Flex built in validator components. Following example calls handleValid and makes it sure that user does not leave inputComponent blank.

<mx:Validator id="reqValid" required="true" source="{inputComponent}" property="text" valid="handleValid(event)" invalid="handleValid(event)"/>

Parameter sequence disturbed : Web Service in Flex

I implemented an application in Flex that used web service, written in PHP with NuSOAP library. The WSDL file that was available for Web Service is as under:

<?xml version="1.0" encoding="ISO-8859-1"?>
<definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://server" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://server">
<types>
<xsd:schema targetNamespace="http://server" >
 <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
 <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
</xsd:schema>
</types>
<message name="saveImgRequest">
<part name="id" type="xsd:string" />
<part name="data" type="xsd:string" />
<part name="emailId" type="xsd:string" />
<part name="notes" type="xsd:string" /></message>
<message name="saveImgResponse">
<part name="return" type="xsd:boolean" /></message>
<message name="purchaseRequest">
<part name="id" type="xsd:string" />
<part name="data" type="xsd:string" /></message>
<message name="purchaseResponse">
<part name="return" type="xsd:boolean" /></message>
<portType name="purchasePortType">
  <operation name="saveImg">
    <input message="tns:saveImgRequest"/>
    <output message="tns:saveImgResponse"/>
  </operation>
  <operation name="purchase">
    <input message="tns:purchaseRequest"/>
    <output message="tns:purchaseResponse"/>
  </operation>
</portType>
<binding name="purchaseBinding" type="tns:purchasePortType">
  <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
  <operation name="saveImg">
    <soap:operation soapAction="http://server/webservice.php/saveImg" style="rpc"/>
    <input><soap:body use="encoded" namespace="http://server" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
    <output><soap:body use="encoded" namespace="http://server" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
  </operation>
  <operation name="purchase">
    <soap:operation soapAction="http://server/webservice.php/purchase" style="rpc"/>
    <input><soap:body use="encoded" namespace="http://server" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
    <output><soap:body use="encoded" namespace="http://server" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
  </operation>
</binding>
<service name="purchase">
<port name="purchasePort" binding="tns:purchaseBinding">
    <soap:address location="http://server/webservice.php"/>
  </port>
</service>
</definitions>

After carefully considering the sequence of parameters in web service method call, I tried to import Web Service through Flex Builder’s Import web service wizard.

Surprisingly, methods that are served by the Web Service have been detected with all parameters. But, with a surprise:

Web Serice Import Wizard in Flex Builder 3

Why is the sequence of parameters been changed? Neither parameters are in ascending/descending order of alphabets nor are in original sequence as are declared!

Can anyone give reason?

Ignoring unwanted sequence through import wizard, I finally implemented Web Service with parameters as are there in WSDL, and it worked fine for me!

private function initAndCallWS():void
{
    saveImageWebService = new WebService();               
    saveImageWebService.wsdl = "http://server/webservice.php?wsdl";
    saveImageWebService.saveImg.addEventListener("result", resultHandler);
    saveImageWebService.saveImg.addEventListener("fault", faultHandler);
    saveImageWebService.addEventListener(LoadEvent.LOAD,loadHandler);
    saveImageWebService.loadWSDL();
}

private function loadHandler(event:LoadEvent):void
{
    saveImageWebService.saveImg("userID","image_content", "email@server.com", "notes");
}

Masking with customized / polygon shape

A typical requirement to create custom closed shape was a big pain till now at my workplace. Many were working to create some run time changeable shape and through that, mask an image. I achieved this; finally, after visiting a blog and a forum for Flash programming. Also, my colleague Mayur helped to organize once I was ready and I explained like Proof of Concept.

For custom shape, you will require a reference to public property of any DisplayObject / UIComponent – that is graphics (flash.display.Graphics)

Now is the real crux.

The next steps work just like you draw something on paper (or Canvas)

// Create and initialize Sprite object
var spriteObj:Sprite = new Sprite();

// Clear graphics
spriteObj.graphics.clear();

// Define style of line (border of the shape)
spriteObj.graphics.lineStyle(1, 0xff00ff);

// Start filling with a selected color
spriteObj.graphics.beginFill(0x00ff00);

// Move to a position to start from (without actually drawing)
spriteObj.graphics.moveTo(x, y);

// Draw a line / curve or anything that is supported by graphics
// This may be used in a loop or recursive manner to draw lines / curves passing through n points
for(...;...;...)
{
	spriteObj.graphics.curveTo(handlerX, handlerY, x, y);
}

// End filling process, just like you put pen aside!
spriteObj.graphics.endFill();

// Define a new canvas and initialize it
var canObj:Canvas = new Canvas();

// Add the just created Sprite object as a raw (not direct UIComponent child) child
canObj.rawChildren.addChild(spriteObj);

// Use over image as a mask, if required
imgComp.mask =  canObj;
%d bloggers like this: