Archive for the ‘tools’ Category
Introducing RacetrackStats v.0.0.1
Introduction
RacetrackStats is an in-Flash performance profiler that gives real-time feedback about how the code it is contained within is performing. It can be found at GitHub:
http://github.com/alecmce/RacetrackStats
RacetrackStats is inspired by and seeks to move forward from Mr Doob’s Stats package (http://code.google.com/p/mrdoob/wiki/stats)
In Action
Below is the first alpha of RacetrackStats in action.
source: http://github.com/alecmce/RacetrackStats/blob/master/test/demo/RacetrackStatsDemo.as
The SWF comprises three small animations (from left to right):
- A mixture of computation and rendering: A simple BitmapData-driven particle system attempting to model smoke using 100000 pixels and a heavy glow filter and blur filter;
- Heavy computation: A prime-factorisation algorithm, which computes 24 * 100 prime factor decompositions per frame. As it continues to run, the numbers get larger which leads to heavier calculation cycles;
- Extremely heavy rendering: A cycadelic circle pattern that has hundreds of semi-transparent circular sprites moving around and overlapping with each other.
The ‘Elastic Racetrack’
RacetrackStats attempts to go beyond Mr Doob’s Stats by measuring how the elastic racetrack is being stretched. The Elastic Racetrack was a phrase coined to describe how the original AVM1 Flash Player segmented each second into frames and attempted to balance the requirements of code, refreshing the screen and doing work like garbage collection. The AVM2 player’s model is sufficiently similar, that the name remains appropriate.
Code Execution
It does this by hooking into the Event.ENTER_FRAME and Event.RENDER events to record when portions of the code start and end. By recording when the ENTER_FRAME starts and when the RENDER starts, the intervening time is taken to be code execution.
Pre-Render Code Execution
Commonly this part of the code cycle is almost unused. If you exploit stage.invalidate and Event.RENDER in order for your classes to execute code after the main code execution has completed, then it will be captured here, between the top-priority Event.RENDER and the bottom-priority Event.RENDER calls.
Rendering
A problem is, the time between the RENDER ending and the ENTER_FRAME starting is used to draw the screen but if time is left over in which the Flash Player has nothing to do, it will idle during this time also. To counteract this, RacetrackStats attempts to throttle the FlashPlayer so that the application is always running as fast as it can, minimising, or even eliminating that idle time. I call this the “render” portion – the “Event.RENDER” event is badly named – screen rendering happens after the RENDER event has finished.
Work To Do
As soon as you add weight like this to an application, the speed at which it runs changes. By measuring the speed, you change the speed. It is the classic scientific paradox. It is mitigated by shrinking down the weight of the stats package as far as possible. At the moment, functionality rather than size is the chief concern, though I have tried to minimize the package by avoiding embedding fonts, and so forth.
I would love to hear what you think about the package, whether positive or negative. I’d also really appreciate it if you use it in your applications. If you have any problems, questions, queries or comments, please leave a comment below, or open an issue on GitHub.
Debugging Web-Embedded Movies in FDT
This is something I find myself setting up again and again for different projects: how to launch the debugger to enable step-through debugging and trace output for a swf that is being viewed in a browser, all inside the FDT environment.
The solution is to create an ant script to launch the debugger, and to run it before the flash movie’s web page is launched. The simple script follows:
debugger.xml
<project name="launch debugger" default="launchDebugger">
<property file="mac.properties" />
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" />
<target name="launchDebugger" description="launches the debugger only">
<fdt.startDebugger projectname="${PROJECT_NAME}" saveLocation="tmp" />
</target>
</project>
This script requires a properties file. I flip between working on my mac at home and on my PC at work, so I tent to create two properties files, mac.properties and pc.properties. This allows me to share files across the two contexts without changing the particular ant scripts. The properties file contains the following:
mac.properties
FLEX_HOME = the path to the flex SDK folder PROJECT_NAME = the FDT project name
With these files defined and stored (probably in an ‘ant’ folder), the debugger.xml should be dragged into the Ant view (if it is not already visible, goto Window > Show View > Ant to make the ant view visible.)
Finally, the most important trick is to go to the Run > External Tools > External Tools Configuration… to bring up a dialog. There you should see your ant script on the left under Ant Build. Choose the JRE tab and specify that the ant script is going to Run in the same JRE as the workspace. I always forget that step, and it always fails to work first time!
Detecting Class-Recursion in AS3
This article has arisen because I found that every now and again while I was writing unit tests for my code, I would find myself coming across stack overflows caused by an infinite recursion of classes. The unit-testing framework didn’t provide a very helpful error message informing me what was going wrong. I decided if I could amend the framework so that it gave me a message which I could resolve easily. It turns out to be harder than it first appeared.
The Recursive Problem
It is unlikely that you would ever write a class like this:
class Recursive
{
public function Recursive()
{
new Recursive();
}
}
However, there is a context where it’s not as unlikely as you’d think. One of the more annoying aspects of test-driven development is the creation of test suites and test classes to reflect each of the packages in your source folder. By convention each package contains an AllTests test suite which adds all the tests within that package. Below is an example:
package mypackage
{
import asunit.framework.TestSuite;
import mypackage.subpackage.AllTests;
public class AllTests extends TestSuite
{
public function AllTests()
{
addTest(new mypackage.AllTests());
addTest(new ExampleTestCase());
}
}
}
If you spotted the deliberate mistake, award yourself ten points. mypackage.AllTests was supposed to add mypackage.subpackage.AllTests as a test suite, but it inadvertently added itself. This will cause a stack overflow in ASUnit. It will tell you that:
Could not create and run test suite: Error: Error #1023: Stack overflow occurred.
It’s accurate, but not massively informative. We can do better than that.
A Generic Solution
I wanted to approach the problem generically before applying any solution to the ASUnit framework. How, then, can you detect that a constructor method calls another instance of the same method?
In AS2 there was an arguments.caller object, which would have allowed me to access the referring method. describeType could be used to inspect the caller and the current method, and check whether they’re the same… unfortunately, arguments.caller is not supported in AS3, as the AS3 Language Reference explains.
However, it is still possible to discover information about the methods in the stack of currently-called elements: by creating (but not throwing) an error. As long as you are running Flash in the debug player, then you can inspect that stack trace created by the error, and determine the sequence of constructions.
Check out the github repository for this approach
The main class in this repository is the RecursionWatcher.as file. The workhorse method is the stackIndicatesRecursion method which takes a generated error and inspects the stack trace that it produces to determine whether class-recursion is taking place.
A Solution for ASUnit?
So far this I’ve created this solution generically in its own repository, and I haven’t tried to integrate it into ASUnit. Some issues need to be thought through:
- Should this sort of solution be integrated into the TestCase or TestSuite class?
- What are the speed implications of adding this? What sort of speed reduction is the extra functionality worth?
- Can the functionality be put into a class which decorates the TestCase, minimising the footprint of the core code changes?
I will be approaching integrating this work into the latest versions of ASUnit in the next few weeks, but I would like to guage whether this is the most appropriate course of action to take, and whether it’s even worth putting this sort of test into the framework. All comments welcome!
Windows, Eclipse and GitHub
Setting up for using GitHub on my mac was a breeze. Setting up at work on Windows was a pain. I think that these steps will satisfactorily setup Eclipse to work with GitHub.
- If you haven’t got a GitHub account, create one;
- Install eGit in Eclipse;
- EGit for Eclipse is at http://www.jgit.org/updates;
- I was unable to install EGit into the FDT ’standalone’ version of Eclipse. If you have this problem you will need to download and install the (superior) Eclipse Classic Version;
- Download and install msysgit from Google Code;
- Create your own ssh key using
$ ssh-keygen -C "your@email.com" -t rsa
- Personally I’d use the “Use Git Bash only” option;
- This will generate your key to (typically):
c:\Documents and Settings\[yourname]\.ssh
Change the folder from .ssh to ssh, otherwise EGit will look in the wrong place;
- In Eclipse, “Import…” a new project and choose “Git Repository”.
- Copy the Public Clone URL from the GitHub repository that you want to clone into the Location URI.
Finding Methods without JavaDoc comments in AS3
If you need to find methods in a project that don’t have JavaDoc comments in them, Java developers can use checkstyle. Unfortunately, it doesn’t appear to work with AS3 files. (At least, in the limited amount of time I’ve had to look at it, I can’t make it work. If you know how to, please let me know!)
Instead, if you want to find uncommented methods in an AS3 project, you can use the following regular expression. It looks for alpha-numeric characters between the end of a variable definition or method and the start of a method, and as such it is not infallible. However, it works for me using Eclipse, and I thought it might be useful for others:
(?s)(}|;)([^\w\}\;]+?)((override |)(private|public|protected)( override|) function)
If you have a superior mechanism for finding uncommented AS3 methods (particularly if it is integrated into Eclipse), please let me know!
