why asyncHandler in FlexUnit fails in capturing TIMERCOMPLETE event? - apache-flex

I am testing timerevent with flex unit. Follwing is the code which i tried ,
it always goes to cmdFailed function (Time out function).I am new to flex unit .any help would be greatly appreciated.
[Before]
public function setUp():void
{
timer = new Timer(12000);
}
[Test(async,order=1)]
public function teststorapidpresenter():void
{
timer.addEventListener(TimerEvent.TIMER_COMPLETE,Async.asyncHandler(this,cmdHandler,20000,null,cmdFailed));
timer.start();
}
private function cmdHandler(event:TimerEvent,passThroughData:Object):void
{
}
private function cmdFailed(event:Event):void
{
fail("Event not dispatched");
}

Yes, classic error here.
By default, repeatCount property of a timer is 0.
That means the time never stops so the TIMER_COMPLETE is never dispatched.
timer.repeatCount = 1
and it should work

Related

Flex 3: is it possible to add an event listender to a boolean variable?

I have a boolean variable, projectsLoaded that is set to false when my application loads. As i'm sure you can imagine, when the final project module loads, I set the variable to be true. Is there a way I can trigger a series of functions to run once that variable is set to true?
You can use setters and getters to execute code when value changes. Just be sure to use the setter instead of setting the private variable value.
EDIT : I just saw you tagged your question with addeventlistener. I edited the code to use that instead.
private _projectsLoaded:Boolean = false;
//this could be done elsewhere, that's just an example
private function init():void
{
addEventListener("projectsLoaded", onProjectsLoaded);
}
public function get projectsLoader():Boolean
{
return _projectsLoaded;
}
public function set projectsLoaded(value:Boolean):void
{
if(_projectsLoaded!=value)
{
_projectsLoaded = value;
if(value)
dispatchEvent(new Event("projectsLoaded"));
}
}
protected function onProjectsLoaded(event:Event):void
{
//your logic here
}

flex upload file component - problems with filereference

The following code is used in a component I name FileUpload.mxml which is used in two three different sections of the flex application.
private var uploadURL:URLRequest = new URLRequest;
private var file:FileReference = new FileReference;
private var media:MediaFacade;
public function browse():void
{
var uUrl:String=""; // force
uploadURL=new URLRequest();
file=new FileReference();
configureListeners();
file.browse(getTypes());
}
private function configureListeners():void
{
file.addEventListener(Event.CANCEL, cancelHandler);
...
if (!Application.application.hasEventListener("uploadFileEvent")) {
Application.application.addEventListener("uploadFileEvent", uploadFile);
}
}
When it is used in the first instanced, it works fine, but when it is used in different sections it gets the following error from the code below:
Error #2037: Functions called in incorrect sequence, or earlier call was unsuccessful.
private function doUploadFile():void
{
try
{
file.upload(uploadURL);
}
catch (e:Error) {
trace(e.message);
}
}
It follows the same sequence every time, i.e., file=new FileReference; configureFileListeners(file); file.browse(); file.upload(uploadURL) but only works on the first instance of the component being created.
Any ideas would be appreciated.
Thanks in advance.
Angus.
browse method only can be call directly from "User-Interaction" event such as CLICK event. If you wrap it in a function or class than that error will occur.
I'm a noob at Flex, but from what I've read:
Try calling .cancel() before .browse() to ensure no event is conflicting.

UIImagePickerController Crashing Monotouch

I am trying to write an application, but it is constantly crashing when using the uiimagepickercontroller. I thought that it might be because I was not disposing of the picker after each use, but it will often freeze up on first run as well. Usually I'll take a picture and it just freezes, never asking to "use" the picture.
Do you have any suggestions? Here is my code. Has anyone gotten this to work?
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
myPicker = new UIImagePickerController();
myPicker.Delegate = new myPickerDelegate(this);
myAlbumButton.Clicked += delegate {
if(UIImagePickerController.IsSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary)){
myPicker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
myPicker.AllowsEditing = true;
this.PresentModalViewController (myPicker, true);
}else{
Console.WriteLine("cannot get album");
}
};
myCameraButton.Clicked += delegate {
if(UIImagePickerController.IsSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)){
myPicker.SourceType = UIImagePickerControllerSourceType.Camera;
//myPicker.AllowsEditing = true;
this.PresentModalViewController (myPicker, true);
}else{
Console.WriteLine("cannot get camera");
}
};
}
private class myPickerDelegate : UIImagePickerControllerDelegate
{
private TestView _vc;
public myPickerDelegate ( TestView controller):base()
{
_vc = controller;
}
public override void FinishedPickingImage (UIImagePickerController myPicker, UIImage image, NSDictionary editingInfo)
{
// TODO: Implement - see: http://go-mono.com/docs/index.aspx?link=T%3aMonoTouch.Foundation.ModelAttribute
_vc.myImageView.Image = image;
myPicker.DismissModalViewControllerAnimated(true);
}
}
Try to call your event handlers code from the main thread by using BeginInvokeOnMainThread().
So my issue was very similar.
Instead of having a delegate class, I had the delegates inline for the picker.
For some reason the app froze every time after talking the image, not stopping in any breakpoint after that.
The solution that worked for me was to use this book:
http://www.scribd.com/doc/33770921/Professional-iPhone-Programming-with-MonoTouch-and-NET-C

Flex text change event

I'm tracking how fast does the text of a textArea change. If it changes faster than 500 ms then i don't want to do anything, but if it doesn't change in 500 ms, i want to call a method.
I tried like this:
public function textchangeListener(e : Event):void
{
if(((new Date).getTime() - changeTime)>500)
{
prepareText();
}
changeTime = (new Date).getTime();
}
This method is the event handler for text change.
But the problem is, if it changes only under 500 ms and after that it doesn't change, then my method won't be called. I make this for a better performance, so the prepareText() is called only when the user stops typing for 500 ms.
How about this...
Once you get the first text change event you can call a procedure like textTimeOut(). It will essentially work like this.
function textTimeOut():void
{
start a timer for 500 ms
set an event listener for it (your prepareText() function)
if textTimeOut is called again before the timer gets to 0,
reset the timer to 500 ms
}
I would use a setTimeout in the event handler and reset it everytime it changes:
var changeTimeout:Number = -1
function handler(e:Event):void {
if(changeTimeout != -1)
clearTimeout(changeTimeout)
changeTimeout = setTimeout(function():void{
changeTimeout = -1
prepareText();
}, 500)
}
So I used a timer. Thanks for the advice. This is what the end result is:
protected var timer:Timer = new Timer(300);
public function AdvancedTextArea()
{
super();
this.addEventListener(Event.CHANGE,textchangeListener);
timer.addEventListener(TimerEvent.TIMER,prepareText);
timer.repeatCount = 1;
}
public function textchangeListener(e : Event):void
{
if(timer.running)
{
timer.stop();
}
timer.start();
}

Best way to execute a function after exactly one frame?

With ActionScript3 for Flash Player 9+, what is the nicest way to call a "once-off" function after exactly one frame?
I am aware of the Timer class and it's uses, and the callLater method on Flex UIComponents (which, glancing through the source, doesn't look very efficient in this scenario). I'm also aware of setTimeout (in flash.utils).
The Timer class and setTimeout utility are both time based, so how would we guarantee that our function will get called after exactly one frame?
From my limited testing it seems that functions passed to setTimeout only execute after at least one frame (try setting the delay to 0). But this is not guaranteed.
Of course, we could listen for Event.ENTER_FRAME events from a DisplayObject, but that seems like overkill for a once-off delayed function call.
Flex was intended to abstract away the frame-based nature of the Flash Player so you will not find much to help you with your problem. The best approach is to listen for ENTER_FRAME as you suggest. If that's overkill (and I'm not sure why you think it is), you could create a helper class which takes a DisplayObject and Function as arguments which will automatically add/remove the ENTER_FRAME event listener for you.
public class NextFrameCommand() {
private var functionToCall : Function;
public function NextFrameCommand(dObj: DisplayObject, func : Function) {
functionToCall = func;
}
public function start() : void {
dObj.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e : Event) : void {
e.target.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
functionToCall.call();
}
}
I haven't tested that code but hopefully you get the idea....
Playing with the solutions provided by Theo and brd6644 I came us with this. It allows multiple functions (with parameters) to be queued and executed in order at the next frame.
public class DelayedFunctionQueue
{
protected var queue:Array;
protected var dispatcher:Sprite;
public function DelayedFunctionQueue()
{
queue = new Array();
dispatcher = new Sprite();
}
public function add( func:Function, ... args ):void
{
var delegateFn:Function = function():void
{
func.apply( null, args );
}
queue.push( delegateFn );
if ( queue.length == 1 )
{
dispatcher.addEventListener( Event.ENTER_FRAME, onEF, false, 0, true );
}
}
protected function onEF( event:Event ):void
{
dispatcher.removeEventListener( Event.ENTER_FRAME, onEF, false );
queue = queue.reverse();
while ( queue.length > 0 )
{
var delegateFn:Function = queue.pop();
delegateFn();
}
}
}
Might be useful to someone.
One way would be to see how many frames per second your project is set for and let the setTimeout function delay for 1 frame time within that setting.
So if your project is set at 24 frames per second, you delay for 42 millisec in setTimeout.
var timerSprite:Sprite = new Sprite();
timerSprite.addEventListener(Event.ENTER_FRAME, oneFrameHandeler);
function oneFrameHandeler(e:Event):void
{
timerSprite.removeEventListener(Event.ENTER_FRAME, oneFrameHandeler);
timerSprite = null;
trace("one frame later!")
}
ENTER_FRAME is not overkill - something like this is short and easy
addEventListener(Event.ENTER_FRAME, function(e:Event):void
{
removeEventListener(Event.ENTER_FRAME, arguments["callee"]);
onceOffFunction();
}

Resources