Useful Flex 2 explorer applications

March 29, 2007

The original style explorer, updated for Flex 2!

Distortion filters and various transitional flips (more info)

Transitions and effects explorer

Filters explorer

Flex 2 primitives explorer

Custom easing equation explorer

and (not written in Flex, but I always use it)

Visualizing Robert Penner’s easing equations

Variable-length argument passing and dynamic method invocation within flex / djangoamf

March 22, 2007

Things get slightly tricky when attempting to dynamically invoke methods on a proxied object, as I discovered. When attempting an AS2-style fix, I also discovered that syntax has changed.

Trapping undefined method calls used to be achieved with the Object.__resolve property in AS2, but this has changed in AS3 / Flex2:

“The Proxy class, which is the replacement for the Object.__resolve property from ActionScript 2.0, allows you to intercept references to undefined properties or methods before an error occurs. All of the methods of the Proxy class reside in the flash_proxy namespace in order to prevent name conflicts.” (from LiveDocs: Language and Syntax- namespaces)

Since djangoamf (and most remote service implementations) use this proxy method to allow calls of the form remoteService.remoteMethod(args) one must perform a little trickery if writing a wrapper method to call the remote service that is itself dynamically invocated. The following method I wrote to wrap around invocations of the remote service; it takes the remote method name and a variable number of arguments, then dynamically invokes the requested method on the proxied service (interesting/relevant items are listed in bold):

(script)

import flash.utils.Proxy;
.
.
.
public function loadRemoteData(callbackObj:*, callbackname,
  methodName, ...args) : void {

    this.callbackObj  = callbackObj;
    this.callbackName = callbackName;

    // place the remote method name
    // at front of passed-in arguments
    args.unshift(methodName);

    // directly call proxy::callProperty
    // bypassing normal dynamic invocation
    Proxy(service).flash_proxy::callProperty.apply(service,
      args);

}
.
.
.
private function handleResult(re:ResultEvent) : void {
    callbackObj[callbackName](re);
}

(mxml)

.
.
.
<s2:RemoteService
    id="service"
    gatewayUrl="http://127.0.0.1:8000/gateway/"
    destination="BlogService"
    useAMF0="true"
    result="handleResult(event)"
    fault="handleFault(event)"
    showBusyCursor="false" />

Thanks to www.docsultant.com for an excellent read on some of the more advanced reflection syntax in Flex / Actionscript.

see: www.docsultant.com: flex internals
also: LiveDocs: AS2 -> AS3 migration / language changes

[flex / django] communications with djangoamf

March 15, 2007

[Update: DjangoAMF has been patched with these changes. Thanks!]

Immediately after I installed DjangoAMF and began playing around I ran into problems. Nothing was working correctly, even though my setup was exactly as the example in the user manual, and Flex was constantly rewarding me with a Client.Data.UnderFlow exception.

I could get the same Flex 2 application working with a gateway running amfphp (which I installed as a control/reference), so I was pretty sure it wasn’t the Flex side of things.

So I began peeking at the transmitted packets with Charles and comparing it to the structure of the remoting envelope. Soon I noticed something a bit, shall we say, dyslexic

Hmm.

*checks DjangoAMF Python code*

Dang.

Haven’t run into this issue in years. Looks like I ran into this issue for the first time because I am running/testing on my non-Intel Powerbook thus breaking the network byte ordering for me.

A quick python fix and test of the changes confirmed my suspicions. Here’s the fix:

In amf/amf0.py, replace


def write_long(l, output):
  d = struct.pack('L', l)
  d = d[::-1]
  output.write(d)

def write_int(n, output):
  d = struct.pack('H', n)
  d = d[::-1]
  output.write(d)

with


def write_int(n, output):
  output.write(struct.pack('H', socket.htons(n)))

def write_long(l, output):
  output.write(struct.pack('L', socket.htonl(l)))

I hope this helps any other Mac programmers who might be struggling with getting this to work; getting these two frameworks running together is a real pleasure to behold. Stay tuned.

[flex / django] frameworks together – do the flango!

March 15, 2007

I am currently working on a project (or two) that utilizes both Flex 2 and Django (I christen thee “Flango”!)

In my view this is taking advantage of Django’s excellent framework, data model, admin interface, etc., while utilizing the power and components inherent in Flex 2 / Actionscript 3 / Flex Builder 2.

While I use Django for pretty much everything, I render pages/components using Flex 2 instead of the Django templates. Templates are used to instantiate the correct Flex .swfs, but outside of that it is completely Flex that handles the UI presentation.

I am very pleased with Django, and both it and Python are a pleasure to work/program with, and I’ve been utilizing DjangoAMF to bridge Flex and Django.

Much more on these technologies working together and apart in future posts.

a google gripe (*gasp*)

March 15, 2007

While it pains me to think that my first posting on this new blog will be a gripe, this is indeed the case.

<gripe>

Google search results (as of this posting) have no indication (as with [pdf] files) that the link is an RSS feed that might spawn an external newsreader.

</gripe>

If I were quickly clicking through these example results, which one should I avoid?

typical google search results

This gripe typically unfolds for me in the following stages:

  • Perform Google search
  • Click on N results (where N is generally > 5)
  • Notice that only M tabs have spawned (M being much less than N)
  • Begin to wonder why my machine has slowed to a crawl
  • Realize that I’ve spawned an RSS subscription feed and frantically attempt to cmd-tab+alt-q before Newsfire has a chance to sync all (horribly-unread-and-way-behind) 20+ feeds
  • Consider starting a blog to enable global google gripe rantings
  • I suppose that, as of this posting, I may remove the final step in this procedure, which pretty much optimizes my gripe algorithm as best as I can.

    Hopefully Google will fix this soon, rendering this sequence an uncomfortable memory.

    Eh? Google? Goooooogle? *thump* *thump* Is this thing on?


    Follow

    Get every new post delivered to your Inbox.