Flex/Flash/Actionscript

Sneaky Flex trick to get the name of any calling functions

Well I’ll be damned, in my last post I wrote about how I was trying to figure out which class was calling addEventListener on a FlexSprite. I couldn’t figure out a way to get the name of the calling class, or the name of the method that called addEventListener(). Well, Almog Kurtser commented that there’s a trick you can do by using the Error class and the getStackTraceMethod() to parse out these strings.

If you call: trace(new Error().getStackTrace()) you’ll get something that looks like:


Error
at MonkeyPatchTest/___MonkeyPatchTest_Application1_creationComplete()[path/to/source/src/MonkeyPatchTest.mxml:4]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\flex_3_beta3\sdk\frameworks\projects\framework\src\mx\core\UIComponent.as:9041]
at mx.core::UIComponent/set initialized()[E:\dev\flex_3_beta3\sdk\frameworks\projects\framework\src\mx\core\UIComponent.as:1165]
at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\flex_3_beta3\sdk\frameworks\projects\framework\src\mx\managers\LayoutManager.as:696]
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.core::UIComponent/callLaterDispatcher2()[E:\dev\flex_3_beta3\sdk\frameworks\projects\framework\src\mx\core\UIComponent.as:8450]
at mx.core::UIComponent/callLaterDispatcher()[E:\dev\flex_3_beta3\sdk\frameworks\projects\framework\src\mx\core\UIComponent.as:8393]

Within that long string you have all sorts of information about every calling function all the way up the stack. You can parse that all out and figure out where in the application you were. You can do this from anywhere in your app.

So I updated the monkey patched event dispatcher example in my last post to use this method and lo and behold we can get the class name of the class that called addEventListener(). We even get the method name and the line number where addEventListener was called.

Now in the FlexSpy example you get much more information and can trace back exactly where the event listener was added. Sweet! A big thanks goes to Almog (and to Alex Harui who Almog references as his source of this little gem).

IMPORTANT NOTE: The Error.getStackTrace() method only works with the DEBUG version of your swf. If you export a release build then a call to Error.getStackTrace() won’t work.

Standard
Flex/Flash/Actionscript

Monkey Patching FlexSprite to list all event listeners on any Flex component

A while back Ben Clinkinbeard asked a question on flexcoders saying “Am I the only one who wishes EventDispatcher exposed its listeners?” The fundamental issue was that he wanted to get a list of all the event listeners that had been added to a given component.

The approach: using FlexSprite
Someone suggested monkey patching UIComponent to add this functionality, since each UIComponent gets notified each time a call to addEventListener is called, and you could keep track of the references locally. The thing is, monkey patching UIComponent is kind of a pain in the ass since it’s such a big class. When you monkey patch a class you basically need a complete copy of the whole class in your code so you don’t lose the functionality of that class. It’s perfectly doable with UIComponent, but gets kinda nasty.

So I was looking for an alternative and realized that the beautifully small FlexSprite class, which is the lowest level class you can get source code for (everything above it like Sprite, etc is built into the player). FlexSprite is under 100 lines of code and almost all of that is comments. When you get down to it there’s only a constructor and a single method in FlexSprite. So that makes it super duper easy to monkey patch the bastard. To refresh everyone’s memory the inheritance goes: Sprite -> FlexSprite -> UIComponent.

So if you’re trying to add in functionality that will trickle down into every component in the Flex framework, and you don’t need stuff specific to UIComponent, then the easiest way is to monkey patch FlexSprite.

The result
The good news: you can get a list of every event listener that is currently added to any component (at least anything that inherits from FlexSprite). This list will tell you the main details of the listeners, like type (ie “change”, “click”, etc), priority, useCapture, and useWeakReference. You also get the time when the listener was added (which is stored using getTimer to indicate the number of milliseconds since the app launched).

So now anything that inherits from FlexSprite (every display object in the Flex framework) has the following additional property and methods:

  • eventListeners – returns an Array of every event listener currently registered with the component. The Array contains ListenerTracker objects, which is a new class that simply holds the details of the listeners (like priority, etc).
  • removeEventListeners(type:String) – this will remove all event listeners for a given event type. You don’t have to have the reference to the actual listener function to remove it.
  • removeAllEventListeners() – removes all event listeners of all types. This completely wipes out all event listeners for the component all at once.

Here’s a very simple demo application that simply adds a button via MXML and shows all the event listeners on that button in a DataGrid. You can click the bottom button to remove all the listeners on the top button, which will effectively disable all interaction with the button, which should make sense.

This movie requires Flash Player 9.

Simple example | source

The bad news: so you get the function that was added as the listener, but you can’t get anything useful out of this, like the actual function name in the code. You also can’t get the name or reference of the object that contains the function, or that made the call to addEventListener. So that blows.

UPDATE: We can actually get the name of the class that called addEventListener(), the method name where it was called, and the exact line number. See my post about a sneaky trick to do this.

Basically you can see how many listeners of each type (and priority, etc) there are and you can remove any individual ones (or all of them at once). But we are not being able to get much information about a Function object itself. In the addEventListener function we get passed a Function, but you can’t get any more information about that object (see the listener column in the above example, it just shows the “function Function () {}” string, which doesn’t help at all). I’ve tried using describeType() on the Function and everything else I could think of but couldn’t figure out how to get any additional useful information about a function. If anyone has any ideas shoot me an email to let me know.

A cooler example
So I remembered seeing a pretty badass Flex library that let you explore all the properties and styles of any ui components in your application. I went back and found it, it’s called flexspy and is a project hosted on Google code created by Arnaud Pichery. So that’s cool, you drop the FlexSpy swc into your app and suddenly you get access to this cool real-time property and style inspector. (BTW, FlexSpy is licensed under the Do What the Fuck You Want To Public License, ha, awesome)

So I went and extended the FlexSpy component and added my own Event Listeners tab to the main inspectors. Now when you launch my version of FlexSpy you can see all the event listeners on whatever component you select. Dope. I added in buttons to let you remove any individual listeners, or all the listeners for any particular component. Here’s a screenshot, and the links to the example app and the source (view source is also enabled on the app).

screenshot0021.jpg

Enhanced FlexSpy demo | source

Standard
Flex/Flash/Actionscript

WindowShade component added to FlexLib

A new Flex container has been added to FlexLib, called the WindowShade. This container shows a header button above or below the content of the container. Clicking the header button opens or closes the panel. This lets you easily create expandable panels in your Flex applications. A single WindowShade container can be used on its own, or you can place a few of them in a VBox to make something similar to an Accordion, except you can have multiple children open at once (similar to Peter Ent’s stack components).

The component was contributed by Dave Glasser, of iDashboards. I initially went back and forth with Dave about the component. At first I thought this was really trying to be an accordion component with multiple open children, in which case I figured if we were going to do that component we should do it right (maybe extend Accordion). But I’ve since been won over to the usefulness of a single WindowShade container, and in my latest project I even used it – 3 times 🙂 So I worked with Dave and we reworked the component a bit, and now I think it’s pretty nifty.

Here’s an example that uses LinkButtons for the headers. You can use any Button control (ie Button, LinkButton, CanvasButton).

This movie requires Flash Player 9.

As a side note, I also contributed a fix from Troy Gilbert that lets you use a CanvasButton in a Repeater. Thanks Troy!

Standard
Flex/Flash/Actionscript

Full video of my 360|Flex Seattle session on Custom Flex Component Development

Since the next 360|Flex is fast approaching, I thought I’d post the full recording of my session at the last 360|Flex in Seattle. You can do whatever you want with this video, embed it wherever, watch it wherever, you can even download the original mp4 video file. Hopefully the embedded video is good enough quality to read the code on the screen, if not go ahead and download the full size version, that’s the best quality we got.

At the next 360|Flex at the end of this month in Atlanta I’ll be speaking on “Using Open Source Flex Projects”. If you’ve never been to a 360|Flex event, maybe this video will give you an idea of what they’re like. An important thing to note in this video is that there might be chunks of silence when people in the audience were speaking. I didn’t do the best job of repeating everything people said, but it wasn’t like I could just repeat questions people asked. The session was really a discussion among lots of people in the audience, and it really had a great community vibe to it, with people answering each others questions and teaching me lots of cool stuff. That’s what I love about the 360 events, it’s just a bunch of dorks hanging out and talking shop.

Standard
Flex/Flash/Actionscript

I’m speaking at the Orange County Flex user group on Thur Feb 7

firefoxscreensnapz015.pngNext Thursday, Februray 7, I’ll be speaking at the Orange County Flex user group about how to use open source Flex code in your own projects. I’ll be covering how to find, download, compile, and use open source as3 libraries, and I’ll be showing off some examples of things you can make without much work by taking advantage of the code that’s already out there. Basically I’ll be talking about how to be lazy and still make cool stuff.

This is a bit of a warm up for my more in depth talk on the same topic at 360|Flex. So the folks in the OC get to be the guinea pigs a bit and help me formulate my 360 presentation. It’s going to be a good time, we’ll hang out, talk about all the cool shit that’s out there that you can use. So if you’re in the southern cali area, come on by next Thursday.

Here are all the important details:

What: OCFlex user group meeting
Date: February 7th
Time: 7pm
Location: FarHeap Solutions offices @ 2601 Main St Suite 1200 : Irvine, Ca 92614

If anyone that’s attending wants to suggest specific open-source libraries they want covered, either leave comments here or shoot me an email.

Standard
Flex/Flash/Actionscript

eBay Widget Contest rules change for Flex developers

I just checked the eBay Widget Design Contest rules page again, and was happily surprised to see two important changes to the rules that now make it feasible for Flex developers to enter the contest. You are now allowed to use open-source code licensed under the MIT or BSD licenses, and your widget can be up to 400 kb. Below are the changed portions of the official rules:

Widget may not exceed 400kb in size

Widget may not incorporate any open source code except for Adobe Flex under the MPL license, or any open source under MIT or new BSD license in addition to source code published by eBay under CDD license;

Awesome. The wording seems a little odd to me (ahh, lawyers…), but the intent is to allow the Flex SDK, any MIT or new BSD code, and the eBay toolkit code that eBay released under the CDD license. So now you’re free to grab any number of open source projects and use them in your entry. Note that this doesn’t apply to every open-source license (understandably), so make sure you don’t get your hands on anything with those nasty GPL viral licenses. But the MIT inclusion covers a huge library of open-source Flex code that’s out there.

They also raised the file-size limit from 200k to 400k. If you’ve developed Flex apps, you know that you’re not likely to have an app less than 200k. I think 400k is a much more reasonable limit, and opens the door to Flex developers.

I’ve been called out.
So I originally bitched and moaned about how I wasn’t going to enter the eBay widget contest because of the restrictive rules about no open source code. That same day I got an email from someone at eBay, spoke with someone on the phone to explain my issues, and now they’ve gone and changed the rules to be accommodating. I was very impressed with eBay’s concern and willingness to listen to developers. So now I guess I have to enter the contest, right? Unfortunately the truth is I probably won’t get my act together to create an entry, but now the only excuse I have is that I’m too busy. I’m going to try to carve out some time to make an entry, but god knows if that will actually happen. When I originally complained, I was hiding my busyness/laziness behind my rant about the rules. Now eBay has gone and done everything I wanted to make the rules better, and I feel like my bluff has been called.

So to all the Flex developers out there, go win ten grand by making an eBay widget. You can use Flex, you can use whatever cool open source code you can find. You’ve got until February 22 to make some cool shit. A big thanks goes to eBay for being awesome and listening. Thanks guys, you rock.

Standard
Flex/Flash/Actionscript

Mint.com uses FlexLib components

James Ward already had a little writeup about Mint.com using Flex for some of their spending habit charting stuff, but what’s even cooler to me is that they’re using a few FlexLib components on the site. I got an email from Jason Putorti, a Flex dev with Mint, letting me know that he’s using the DraggableSlider component, and I took a look and also saw that they’re using the ScrollableArrowMenu. Here’s a screenshot of both the components in use:

firefoxscreensnapz014.png

The menu showing the list of cities there is the ScrollableArrowMenu and above that there’s the DraggableSlider that lets you select the date range you’re using for the chart. Sweet!

Standard
Flex/Flash/Actionscript

More FlexLib bugfixes and updates

Yesterday I made some updates to FlexLib, mostly to sort out some bugs, a few of which I inadvertently created with the previous release. Here’s the list of issues addressed:

  • Issue 71: Drop-down tab-list fails to activate when using states with constant names
  • Issue 72: SuperTabNavigator -Close Tab-
  • Issue 76: Make TabReorderEvent Cancelable/Hookable in SuperTabNavigator
  • Issue 77: Tabbar title change does not resize Tabbar
  • Issue 78: getChildren in ButtonScrollingCanvas

The first four issues are fixes for SuperTabNavigator issues. #71 and #72 were new bugs I introduced with the .2.2 release without realizing it. My bad. This is what happens when the FlexLib QA team consists of me after about 5 beers. #76 is an added feature for the SuperTabNavigator. #77 is a bug fix for a SuperTabBar bug, and #78 is a fix for ButtonScrollingCanvas for what I guess has been a bug since that component was added.

I also managed to put a up a version .2.3 briefly that had an even better bug with ButtonScrollingCanvas that rendered that component and the SuperTabNavigator inoperable. Woopsies again. 🙂 I updated the release and the current version (.2.3.1) should have things all sorted out. There were around 250 downloads of the .2.2 release (jesus you people move fast), so if you downloaded that one, make sure to get the latest and update, that .2.3 release is whack.

There’s also a new component dropped into FlexLib, but I’ll blog about that one tomorrow since I haven’t done the writeups for the component description on the wiki pages yet. But it’s in there.

w00t. Keep reporting bugs.

Standard
Maps

Tracking my location – forever

I have recently started tracking my geographic location, with the intent of keeping an automatic log of where I am, ideally for the rest of my life. I have no idea how long I’ll realistically be able to keep this updated, but I figure “forever” sounds like a good goal.

Method
firefoxscreensnapz011.pngI just got my very first Blackberry (the Curve), which has built-in GPS. The first thing I wanted to figure out (after getting gmail on the phone) was how to store position reports automatically. There are a few pieces of software that sort of do this, although some applications store the position logs locally on the SD memory card, which you then download to your computer. There are also some subscription-based services catered more toward enterprise-level fleet management that do way more than I need (TeleNav Track, Accutracking) . The SD card approach is no good for me. I’m lazy, and I know there’s no way I’m ever going to transfer the position log from my phone to my computer. The subscription service is a bit more realistic (Accutracking even has a REST API), but I’m not excited about having to keep a subscription paid and active and rely on someone else for my reports. The only real workable solution was to find an application that automatically sent the position information to a web server, and ideally to my own webserver so I can have full control over the data.

firefoxscreensnapz012.pngEnter Mologogo. Mologogo is a free application and service for GPS-enabled phones that does exactly what I wanted. It runs automatically every few minutes (mine’s set to run every 5 minutes) and sends your position report to the Mologogo online service, which keeps track of your points. That’s halfway to what I needed. The icing on the cake is that the Mologogo application has an awesome feature that lets you set your own URL that the service will also send the position report to. Bingo. This lets you save your position reports in your own database to do whatever you want. I grabbed some of the sample PHP code from the Mologogo wiki and installed it on my personal web server. After configuring the Mologogo Blackberry app I was getting position reports logged in my database.

Why?
This is not about showing where I am in real-time. This is not about “life-streaming” or “life casting” or whatever the current buzzwords are for letting strangers watch every moment of your life. I do not plan on showing my current location on my blog, or letting people see exactly where I am as I’m there. I’m not going to do that for a few reasons, and privacy is one of them I guess, although I’m not really freaked out about the idea of having my current location be public knowledge. The main reason is that I think that stuff is boring as hell. I watched Justin.tv for all of about 5 minutes, and the entire draw of that kind of lifecasting is the hope that the person you’re watching is going to do something stupid, which usually happens specifically because they’re living to entertain their audience. Other people (in fact most of the people who use Mologogo I assume) like the concept of simply letting people see their latest position reports. But why? I don’t find the idea of viewing where some random guy (or even a good friend) is at the current instant compelling. I suppose if all my friends automatically told me where they were that could be kind of cool and helpful for meeting up. But whatever, that’s semi-useful and still boring.

This is about analyzing historical data. It’s about the visualization of years, the visualization of decades. It’s about being able to see the geographic context of my life. I probably won’t do anything with this data for a year or two. It only becomes truly valuable after extended periods of time.

To try to think about how much data we’re talking about here’s the approximate math:

1 report every 5 minutes = 12 reports an hour = 288 reports a day = 105,120 reports a year = 1 million reports a decade

So theoretically let’s say I can somehow figure out how to actually do this constantly until I’m 80 years old. That would be about 5 and a half million records that would catalog my movement around the world for most of my life. That amount of data is already easy to store online. I can store millions of records like this in an inexpensive hosted database, ideally duplicated in multiple locations for redundancy. So the challenge isn’t about how to store the data, it’s about what to do with it, and that’s where it starts to get fun.

Visualizing the geospatial context of life
The important things in your life have a geographic context. Moving to a new city, changing jobs (even if that just means a slightly different commute), traveling on vacation, etc etc. The geographic movements of your life are directly tied to meaningful experiences. Being able to visualize those movements is like having a picture of a certain time of your life.

I wish I had the data for the past few years. It would have shown me in college, then moving to San Francisco. I could have seen the daily commute I did for a few years, and then the change to working from home. Imagine a heatmap on a map showing where I spend my time. While I was commuting to work you would have been able to make out the route of the train I took every day, and the amount of time I spent simply getting to and from the office. Compare that with my current lifestyle, which now involves either working from my home or my girlfriend’s place, which would also show a kind of “commute”, but this one is very different. This commute represent a shift in where I spend my time, and even beyond showing a change in my work life, it also signifies the strengthening of our romantic relationship. This is a visual representation of a very meaningful part of my life. Being able to visually see this movement is a way to quantify important changes. I imagine creating some amazing looking visual images of this type of data and hanging them on the wall. A single image would represent so much.

Challenges
The biggest challenge is going to be keeping new data updated and old data accessible as technology changes. In another year or two I will have a different mobile device, at which point I’ll have to figure out how to use the new device to keep the position reports updated. In another ten years who knows what kind of device I might be carrying around in my pocket. There’s just no way to predict that kind of stuff. So every few years I’ll have to figure out how to keep my reports updated using new technology. I’ll also have to adapt to changes in how I store that data. Storing it in a database works well now, but inevitably I’ll have to migrate that data from one database to another, or even move from a relational database to some other form of storage. This means I’ve got to either stay geeky enough to know how to implement this stuff for the rest of my life, or I’ve got to figure out a solution that literally requires no changes for the next few decades (I don’t think this is at all possible).

There are also some more immediate challenges. I don’t know how to keep my positions logged as I travel internationally yet. Even as I’m in the US I’ve got to ensure that the logging software is always running on my phone. My phone needs to be on at all times for the reports to come in. Ideally I’m going to try to write my own custom software to do exactly what I want, just so I know how it works under the hood in case something breaks or I upgrade devices. I’m not stoked about the fact that I’m tied to software written by someone else. I’ve also obviously got to keep the webserver that receives the reports up and running at all times. I’ll probably try to move to more of a database in the cloud approach using Amazon SimpleDB and EC2 so I can rely on Amazon instead of my current web host (I imagine I’ll always be relying on some company to handle this kind of stuff).

I’m excited about the possibilities for using this data in a few years, I just hope I can keep the position feed coming in.

Standard
Flex/Flash/Actionscript

Got my bling for 360|Flex

My 360|Flex shirts and my bedazzler just arrived, so I’m now officially pimped out and ready for 360|Flex in Atlanta next month.
atl_shirt3.jpgliljohnatl.jpg
The picture doesn’t really do the shirt justice, but in real life as I move it sparkles, take that Lil John.

A few pictures of the bedazzling in progress:
atl_shirt1.jpgatl_shirt2.jpg

You can order your own shirt with the bling 360|Flex logo here. Assuming I have extra rhinestones I’ll probably bring the bedazzler to the conference, so if you want to get your shine on between sessions you can pimp your own gear. I’ll also have a few extra bedazzled shirts, one of which is going to the winner of the Degrafa contest.

If you haven’t made up your mind about coming to 360|Flex you need to go buy your ticket now.

Standard