Wednesday, December 1, 2010

Flex - Speed Up Performance

Here is some tips for speed up flex application.

1. Always use weak reference when and event is initialize as well as used removefromstage event and in that event clear all object and listener and use System.gc() for release memory.

2. Maximum use ActionScript Class (.as class) instead of used direct component of vbox , canvas etc... so when we need to release memory we easily remove this object from memory.

3. Code Optimization - Create common single instance class for same function of different location as well as try minimize function and create one global function for similar functionality.

4. If application is medium / large then use module and also give separate style sheet on each module and set minimum connection with Main application of this module. When module is no need in memory then remove module and clear all it's object as well as used System.gc() for release memory.

5. Some tips for release memory :

i) When UrlLoader , File , FileReference , ArrayCollection used then after finish of used close / stop / null / finished / removeall this object which is internally given in this object.

ii) Used CatchAsBitmap when object used repeated many times.

iii) Minimum used of BindingUtility and don't forget to clear ChangeWatcher object which is generated when BindingUtility is set.

iv) Possible then separate used .as of each mxml file as well as maximum create object dynamic so after finishing his work you can remove it from parent.

v) Maximum use vector design which are generated in flash or in flash buider 4's skinn or used graphics utility.


6) Try to minimum image load in to your system when any module/object is currently running if it's required to open many high resolution / big sized imaged then load low resolution/ low size version of this image in front so then occupy less memory.

7)Last one use profiler so you know each object's memory size and manage your coding according to size.

Thursday, November 11, 2010

Rotate & Scale From Center Using Matrix and mouse scroll

If you want to rotate from center then move center point to 0,0 and then after rotate reset it's to original.

Here is some sample code.

"<"mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init()"">"
"<"mx:Script">"
"<"![CDATA[
import mx.events.FlexEvent;

private var st:Number = 0;
private var img:Box;

private function init():void
{
systemManager.addEventListener(MouseEvent.MOUSE_WHEEL, doMouseWheel);
can.setFocus();
}
private function mouseDownH(event:MouseEvent):void
{
event.currentTarget.startDrag(false,new Rectangle(0,0,can.width - event.currentTarget.width ,can.height- event.currentTarget.height));
}
private function mouseUpM(event:MouseEvent):void
{
event.currentTarget.stopDrag();
}
private function rotateright():void
{
if(st == 360)
st = 0;
st = st + 5;

var ofx:Number = img.width/2;
var ofy:Number = img.height/2;
var radians:Number = st * (Math.PI / 180.0);
var m:Matrix = new Matrix();

m.translate(-ofx, -ofy);
m.rotate(radians);
m.translate(ofx, ofy);
m.concat(img.transform.matrix);
img.transform.matrix = m;

st = st - 5;
}
private function rotateleft():void
{
if(st == 0)
st = 360;

st = st - 5;

var ofx:Number = img.width/2;
var ofy:Number = img.height/2;
var radians:Number = st * (Math.PI / 180.0);
var m:Matrix = new Matrix();

m.translate(-ofx, -ofy);
m.rotate(radians);
m.translate(ofx, ofy);
m.concat(img.transform.matrix);
img.transform.matrix = m;

st = st + 5;
}

private function complateLoad(event:Event):void
{
Bitmap(event.currentTarget.content).smoothing = true;
event.currentTarget.x = (can.width/2) - (event.currentTarget.width / 2);
event.currentTarget.y = (can.height/2) - (event.currentTarget.height / 2);
}
private function doMouseWheel(event:MouseEvent):void
{
trace(event.delta);
var ofx:Number = img.width/2;
var ofy:Number = img.height/2;
var m:Matrix = new Matrix();
m.translate(-ofx, -ofy);
if(event.delta "<" 0)
{
m.scale(img.scaleX + 0.2,img.scaleY + 0.2);
}
else
{
if(img.transform.matrix.a > 1)
{
m.scale(img.scaleX - 0.2,img.scaleY - 0.2);
}
else
{
return;
}
}
m.translate(ofx, ofy);
m.concat(img.transform.matrix);
img.transform.matrix = m;
}
private function selimg(curimg:Box = null ):void
{
if(curimg != null)
img = curimg;
for each(var objb:Box in can.getChildren())
{
objb.setStyle('borderThickness','1');
objb.setStyle('borderStyle','solid');
objb.setStyle('borderColor','#ffffff');
}
if(curimg != null)
{
img.setStyle('borderThickness','1');
img.setStyle('borderStyle','solid');
img.setStyle('borderColor','#00ff00');
}
}
]]">"
"<"/mx:Script>
"<"mx:Canvas id="can" height="500" width="800" backgroundColor="#cdcdcd" ">"

"<"mx:Box id="imgb1" mouseDown="mouseDownH(event)" mouseUp="{mouseUpM(event)}"
borderThickness="1" borderStyle="solid" borderColor="#ffffff" moveEffect="Blur" ">"
"<"mx:Image id="imgX1" source="GoogleIcon.jpg" complete="complateLoad(event)" click="{selimg(imgb1)}" /">"

"<"/mx:Box">"

"<"mx:Box id="imgb2" mouseDown="mouseDownH(event)" mouseUp="{mouseUpM(event)}"
borderThickness="1" borderStyle="solid" borderColor="#ffffff" moveEffect="Blur" ">"
"<"mx:Image id="imgX2" source="GoogleIcon.jpg" complete="complateLoad(event)" click="{selimg(imgb2)}" / ">"

"<"/mx:Box ">"

"<"/mx:Canvas ">"
"<"mx:Button label="Right" click="rotateright()"/ ">"
"<"mx:Button label="Left" click="rotateleft()"/ ">"
"<"mx:Button label="clear selection" click="selimg()"/ ">"
"<"/mx:Application ">"

Rotate & Resize using Matrix

In the flex matrix object have 6 property a,b,c,d ,tx,ty .
In this matrix a used for scaling on width , d is used for scaling in height ,b is used for tilt ( moving second part on vertical side i.e. right part ) , c is used for tilt ( moving second part on horizontal side i.e. bottom ),tx is used for move x position , ty is used for move y position.

Internally rotate function and filter is also working on this matrix base.

Here is some sample code of that.




"<"mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
width="1200" height="900" applicationComplete="appcomp()"">"
"<"mx:Script">"
"<"![CDATA[
private var mts:Matrix;
private function appcomp():void
{
mts = img.transform.matrix;
if(mts)
{

ha.value = mts.a;
hb.value = mts.b;

hc.value = mts.c;
hd.value = mts.d;

htx.value = mts.tx;
hty.value = mts.ty;



}
}
private function chagneValue():void
{
var mt:Matrix = new Matrix(ha.value,hb.value,hc.value,hd.value,htx.value,hty.value);
img.transform.matrix = mt;
mt = null;
}
private function setOrg():void
{
img.transform.matrix = mts;
appcomp();
}
private function setVal():void
{
setOrg();

/* var oldtx:Number = img.transform.matrix.tx;
var oldty:Number = img.transform.matrix.ty; */

var angNum:Number = Number(ang.text);

var cala:Number = Math.round(Math.cos(angNum));
var calb:Number = Math.round(Math.sin(angNum));
var calc:Number = - Math.round(Math.sin(angNum));
var cald:Number = - Math.round(Math.cos(angNum));

lbSetVal.text = "a. cos("+ angNum +") - > " + cala.toFixed(0) + " b. sin("+ angNum +") - > " + calb.toFixed(0) + " c. -sin("+ angNum +") - > "+ calc.toFixed(0) + " d. -cos("+ angNum +") - > "+ cald.toFixed(0);

var mtn:Matrix = new Matrix(cala,calb,calc,cald);
img.transform.matrix = mtn;
mtn = null;
}
"]]>"
"<"/mx:Script">"
"<"mx:HBox width="100%"">"
"<"mx:Label text="a"/">"
"<"mx:HSlider id="ha" maximum="5" minimum="-5" tickInterval=".1" change="chagneValue()"/">"
"<"mx:Label text="b"/">"
"<"mx:HSlider id="hb" maximum="5" minimum="-5" tickInterval=".1" change="chagneValue()"/">"
"<"/mx:HBox">"
"<"mx:HBox width="100%"">"
"<"mx:Label text="c"/">"
"<"mx:HSlider id="hc" maximum="5" minimum="-5" tickInterval=".1" change="chagneValue()"/">"
"<"mx:Label text="d"/">"
"<"mx:HSlider id="hd" maximum="5" minimum="-5" tickInterval=".1" change="chagneValue()"/">"
"<"/mx:HBox">"
"<"mx:HBox width="100%"">"
"<"mx:Label text="tx"/">"
"<"mx:HSlider id="htx" maximum="100" minimum="-100" tickInterval=".1" change="chagneValue()"/">"
"<"mx:Label text="ty"/">"
"<"mx:HSlider id="hty" maximum="100" minimum="-100" tickInterval=".1" change="chagneValue()"/">"
"<"/mx:HBox">"
"<"mx:HBox width="100%"">"
"<"mx:Label text="Angle"/">"
"<"mx:TextInput id="ang" text="0"/">"
"<"mx:Button label="SET" click="setVal()"/">"
"<"/mx:HBox">"
"<"mx:HBox width="100%"">"
"<"mx:Label id="lbSetVal" /">"
"<"mx:Button label="Set Original" click="setOrg()"/">"
"<"/mx:HBox">"

"<"mx:Canvas id="can" width="1000" height="700" horizontalCenter="0" verticalCenter="0" backgroundColor="#CDCDCD"">"
"<"mx:Canvas horizontalCenter="0" verticalCenter="0" ">"
"<"mx:Image id="img" source="@Embed('Sunset.jpg')" scaleContent="false"/">"

"<"/mx:Canvas">"
"<"/mx:WindowedApplication">"

Tuesday, November 2, 2010

Set Focus SWF File

Hi,

There are many ways to focus your swf file when it's loaded.

1. Using HTML + Javascript code :
"<" body scroll='no'onLoad="document.getElementById('${appSwfVarname}').focus();" ">"
or
"<" body scroll='no'onLoad="document.getElementById('swffilename').focus();" ">"

2. Using ActionScript Code :

ExternalInterface.call('function browserFocus(){document.getElementById(\'swfname\').focus();}');
txtUserName.setFocus();

Saturday, August 7, 2010

Open Photoshop through AIR 2.0

1). If you have old SDK just get it AIR 2.0 SDK from Adobe site. Overrite this in to old AIR 1.5 To AIR 2.0.


2). If you have old project just go on WindowedApplication's xml page in that change
first line to
"<" application xmlns="http://ns.adobe.com/air/application/2.0" ">"

also add extra attribute if not available.

"<" supportedProfiles ">" extendedDesktop "<" / supportedProfiles ">"

Now your application is capable to run native process and open any exe or dmg file through native process.


I just create below class for open photoshop via AIR application. For getting response from photoshop's here one file photoshopRead.txt is created through javascript. When process is finish this file is write a return result and in action script site timer is check response and read this file so we get finished return result.

I hope this will use full everyone who want to call a window application through AIR.


package com.ysi.manager
{
import flash.desktop.NativeProcess;
import flash.desktop.NativeProcessStartupInfo;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.TimerEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.system.System;
import flash.utils.Timer;
import flash.utils.setTimeout;

public class MgrPhotoshopCalling
{
// Variable Declaration
private var photoshopExePath:String = "C://Program Files//Adobe//Adobe Photoshop CS4//Photoshop.exe";
private var jsFileToCall:String = "D:\\FlexProjectSVN\\YSIPrototype\\src\\FinishLayoutToPhotoshop.js";
private var responseFileWrite:String = "C:/wxyz.txt";
private var procarg:Vector.;
private var returnHandler:Function;
private var fileCreate:File;
private var filePR:File;

// VARIABLE OF PROCESS
private var process:NativeProcess;
private var nativeProcessStartupInfo:NativeProcessStartupInfo;
private var filePhotoshop:File;

// TIMER VARIABLE
private var timer : Timer;
private var fileResponse:File;
private var fileStream : FileStream;
private var responseCheckstr : String ;
private var currentScriptExecutedTime : String;

public function callPhotoShop(scriptData:String,retFunction:Function):void
{
var isErr:Boolean = false;
returnHandler = retFunction;
if(NativeProcess.isSupported)
{
filePhotoshop = new File(photoshopExePath);
if(filePhotoshop.exists)
{
fileResponse = new File(responseFileWrite);
if(fileResponse.exists)
{
fileResponse.deleteFile();
}

fileResponse = null;

filePR = new File(File.applicationDirectory.nativePath + "/data/scriptFile/photoshopRead.txt");
responseFileWrite = filePR.url;
filePR = null;

fileCreate = new File(File.applicationDirectory.nativePath + "/data/scriptFile/photoshopExectue.js");
// CRETE PHOTOSHOP EXECUTE FILE IN PATH
var fswrite:FileStream = new FileStream();
fswrite.open(fileCreate, FileMode.WRITE);
fswrite.writeMultiByte(scriptData, 'utf-8');
fswrite.close();
fswrite = null;

jsFileToCall = fileCreate.nativePath;

// Create native startup info
nativeProcessStartupInfo = new NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = filePhotoshop;

// Create Vector array to passing a artument
procarg = new Vector.();
procarg.push("start");
procarg.push(jsFileToCall);
nativeProcessStartupInfo.arguments = procarg; // Set Native Proegress Argument

// Create native process object for calling a exe / system's executable file
process = new NativeProcess();

// SET ERROR HANDLER
process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA ,onError,false,0,true);
process.addEventListener(IOErrorEvent.STANDARD_ERROR_IO_ERROR ,onError,false,0,true);
process.addEventListener(IOErrorEvent.STANDARD_INPUT_IO_ERROR ,onError,false,0,true);
process.addEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR ,onError,false,0,true);
process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA ,onError,false,0,true);

// CALL NATIEVE PROCESS
process.start(nativeProcessStartupInfo);
timerCallStart();
}
else
{
trace("Photoshop's Executable file not found....");
isErr = true;
}
}
else
{
isErr = true;
}

if(isErr && returnHandler != null)
{
returnHandler();
}
}
private function onError(event:*):void
{
trace("Error....\nEvent:..."+ event.type);

if(returnHandler != null)
{
returnHandler();
}
}

private function getJsResponse(event : TimerEvent):void
{
fileResponse = new File(responseFileWrite);
if(fileResponse.exists)
{
currentScriptExecutedTime = fileResponse.modificationDate.time.toString();
if(fileStream != null)
{
fileStream = null;
}

fileStream = new FileStream();
fileStream.open(fileResponse, FileMode.READ);

if(currentScriptExecutedTime != "")
{
responseCheckstr = String(fileStream.readUTFBytes(fileStream.bytesAvailable));
timer.removeEventListener(TimerEvent.TIMER,getJsResponse);
timer.stop();
timer = null;

fileStream.close();
fileStream = null;

setTimeout(removeResponseFile,10);
}
}
else
{
trace("YSI Response file not found....");
}
}

// START TIMER
private function timerCallStart():void
{
timer = new Timer(1000,0);
timer.addEventListener(TimerEvent.TIMER,getJsResponse);
timer.start();
}

// REMOVE TEMPORARY FILE AND CALL RETURN FUNCTION
private function removeResponseFile():void
{
// DELETE RESPONSE FILE
if(fileResponse && fileResponse.exists)
{
fileResponse.deleteFile();
}

// DELETE PHOTOSHOP EXECUTABLE FILE
if(fileCreate && fileCreate.exists)
{
fileCreate.deleteFile();
}

// CALL RETURN FUNCTION
if(returnHandler != null)
{
returnHandler(responseCheckstr);
}

// CLEAR VARIABLE
procarg = null;
returnHandler = null;

// VARIABLE OF PROCESS
process = null;
nativeProcessStartupInfo = null;
filePhotoshop = null;

// TIMER VARIABLE
timer = null;
fileResponse = null;
fileCreate = null;
fileStream = null;

System.gc();
}
}
}

Friday, May 28, 2010

CairnGorm Example, MVC Architecture

1) Service Controller:
------------------------
All USed services is define in service controller
Eg.

"<" ?xml version="1.0" encoding="utf-8"? ">"
"<" cairngorm:ServiceLocator xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:cairngorm="com.adobe.cairngorm.business.*" ">"


"<" mx:WebService id="projectService"
wsdl="{ModelURL.API_WEBSERVICE}"
useProxy="false"
showBusyCursor="true" ">"
"<" /mx:WebService ">"



"<" /cairngorm:ServiceLocator ">"


2) Front Controller:
------------------------
All Command are linked with related event in this section for each event it's command is exists and it's preinitialize here.
Eg.

package com.project.control
{
import com.adobe.cairngorm.control.FrontController;
import com.zmarketing.zebra.commands.*;

public class projectController extends FrontController
{
public function projectController()
{

this.addCommand( projectController.GETALLUSER_EVENT, GetAllUserCommand );

}

// Webservice Event
public static const GETALLUSER_EVENT : String = 'GetAllUser';



}
}


2) Event :
------------------------

Event is extend from CairngormEvent and in default constucter it's calling a super class and register here.
Eg.


package com.project.control
{
import com.adobe.cairngorm.control.CairngormEvent;

public final class GetAllUserEvent extends CairngormEvent
{
public function GetAllUserEvent() : void
{
super( projectController.GETALLUSER_EVENT );
}
}
}


2) Command :
------------------------

In Command there is implement two interface ICommand, IResponder which have method of
i. execute - > used while dispatch event at that time initialize delegate and calling delegate function.
ii. result - > When result is comes at that time return in this function.
iii. fault -> Call when any fault while calling.



package com.project.commands
{
import com.adobe.cairngorm.commands.ICommand;
import com.adobe.cairngorm.control.CairngormEvent;
import com.project.business.GetAllUserDelegate;
import com.project.model.ModelLocator;
import com.project.vo.voAddUpdateCampProductIndustryType;

import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.rpc.IResponder;

public class GetAllUserCommand implements ICommand, IResponder
{
private var model : ModelLocator = ModelLocator.getInstance();

public function execute( event : CairngormEvent ) : void
{
var delegate : GetAllUserDelegate = new GetAllUserDelegate( this );
// This is passed for initialize responder which curretly point to
// result function of this command.

delegate. GetAllUser( event );
// event argument is used for gettting event.data for paramenter as well as
// if any extra cairngormHandler apply we get this handler by event.handler
}

public function result( data : Object ) : void
{
if( data.result )
{

}

}

public function fault( info : Object ) : void
{
Alert.show( "GetAllUserCommand.as\n" + info.toLocaleString(), 'Error' );
}
}
}


2) Delegate :
------------------------

Used for calling backend services and applying responder.
Eg.

package com.project.business
{
import com.adobe.cairngorm.business.ServiceLocator;
import com.adobe.cairngorm.control.CairngormEvent;

import mx.rpc.AsyncToken;
import mx.rpc.IResponder;

public class GetAllUserDelegate
{
private var responder : IResponder;
private var service : Object;

public function GetListALLCampProductIndustryTypeDelegate( responder : IResponder )
{
this.service = ServiceLocator.getInstance().getWebService( ServiceConst.servicename ).getOperation( ServiceConst.oprGetAllUser );
// Get service name and operation here

this.responder = responder;
// responder is a related cairngormCommand's responder which call a result function of command while get result.
}

public function GetAllUser( event : CairngormEvent ): void
{
// take AsyncToken for asynchronize calling
// and apply extra CairngormHandler using event.handler.
// you can also get data using event.data if needed to pass parameter.

var token:AsyncToken = this.service.send("paramenters if needed");
token.addResponder( responder );
token.addResponder( event.handler );
}
}

}



Calling Example :
-----------------------

// Create a new Event , apply data on it and if required add extra handler here is getAllUserResultHandler
var getalluser:GetAllUserEvent = new GetAllUserEvent();
getalluser.data = userid;
getalluser.dispatch( new CairngormResponder( getAllUserResultHandler ) );


private function getAllUserResultHandler( event:ResultEvent ) : void
{
// calling when get server side response.
}