Posts Tagged ‘actionscript

24
Sep
09

Do they test at all?

I’ve noticed that there are a lot of sites out there that have swfs throwing Errors (*).  It’s the most annoying thing about having to use the debugger version of the flash player. I don’t want to look at other coders sloppy error handling, but there seems to be no choice. Check Microsofts Xbox Live site for instance: http://live.xbox.com/nb-NO/default.aspx – it pops an error window with: Error #2044: Unhandled IOErrorEvent:. text=Error #2035: URL Not Found. The site is just a random example – Microsoft is no better or worse than others. Continue reading ‘Do they test at all?’

28
Jul
09

Flex API bug

I just ran into an issue that looks like a bug in the Flex API. The DragManager is used for dragging and dropping between flex components, and it can also be used to implement drag and drop quite easily in your own projects. It’s (mostly) well implemented and the syntax is straightforward. To start a drag, use DragManager.doDrag(dragInitiator, dragSource, mouseEvent). The details are explained in the documentation.

The bug I encountered is in the dragSource part of the call above – it’s an instance of  DragSource class, used to store data being dragged. You add data with myDragSourceInstance.addData(myData, “identifyingString”). Nice and sensible. The problem occurs when data is retrieved through myDragSourceInstance.dataForFormat(“identifyingString”). It returns Object as data can be of any type. Here’s the method from DragSource:

public function dataForFormat(format:String):Object
 {
 var data:Object = dataHolder[format];
 if (data)
   return data;

 if (formatHandlers[format])
   return formatHandlers[format]();

 return null;
 }

But if the data you added is numeric zero – 0 – the test if(data) will return false and the method will return null instead of numeric zero. Bummer! I suspect that if (data || data === 0) would be better.

The workaround I used was to set data as a string instead. As data return is untyped, we need to cast it anyhow.

What do you think? Has Adobe implemented the method correctly or is this a bona fide bug?

28
May
09

Open challenge: Dynamic ContextMenu

Inspired by the very enjoyable challenge from my friends at Apt, we’re doing our own. In a recent project I needed a contextMenu which allowed the user to select the number of pictures to show in a ad template. The choices change with the size of the ad, so every time the context menu is shown, it’s regenerated first. But for the challenge, you can skip the regenereation bit.

I’ll post my solution on tuesday (2.jun)

Continue reading ‘Open challenge: Dynamic ContextMenu’

19
May
09

Modulo (%) – the designer’s best friend

I became a programmer because I was a lazy designer. That is lazy as in “Why create fifty animations that are almost the same”, not “bah – good enough, customer isn’t going to care”. I want top results with as little effort as possible. So actionscript was the way to cut down on unwieldy timelines.

The downside of not having a programming degree is that a few of the useful concepts and methods remain obscured in a corner. As with modulo. For those of you with a maths degree, just skip down a few paragraphs. Designers – bear with me.

Modulo is a maths operator like multiply and divide are. It is most similar to divide as it returns the remainder from an integer division. Quick example: 13 % 10 = 3 because 13 can be divided once by 10 with three remaining. 23 % 10 is also three as 23 can be divided twice by 10 with three remaining.

So why should I care, the designer asks, this is all very interesting, but what practical value does it have? One scenario is my contribution to this mini challenge from Apt, although SIN is probably better in that case. I’ve used it most when laying out n-objects in a grid to calculate x-position. As % returns the remainder, you can multiply count and x-step and do a modulo on total width.

An example:

function placeItems():void {
  var numItems:int=45;
  var xstep:int=15;
  var ystep:int=15;
  var totalWidth:int=150;
  var item:MovieClip;
  for (var i:int = 0; i<numItems; i++) {
    item=createAnItem();
    item.x = (i*xstep)%totalWidth;
    item.y = Math.floor((i*xstep)/totalWidth)*ystep;
  }
}

placeItems();

function createAnItem():MovieClip {
  var item:MovieClip = new myItem();
  addChild(item);
  return item;
}

Which results in this if you have a blue square in the library exported to actionscript as ‘myItem’

modulotest

All the magic is in the last two lines of the for…next loop, it places items in a grid without needing help counters.
Look at item.x = (i*xstep)%totalWidth. It multiplies item count with distance between items and does a modulo on total width. I.e., if i*step is 330, 330%150 = 30. Combined with stepping y down with whole multiplies, we get a nice grid. Y value – if i*step is 330, it gives  2.2 when divided by total width, lose the decimal and we know it in row 2.

It’s super easy to change parameters. Set x/y-step or total width and you’re done. Just keep total width divisible by x-step, else the gird gets staggered.

Anyone else with good examples of modulo for layout?

20
Apr
09

Server result, who called?

I ran into a problem the other day. We integrate our flash application with a server-side image archive, allowing browsing from the flash front-end. That means loading a tree structure and contents of all folders. We only load the structure initially to optimize bandwidth usage – data about the contents of folder is loaded when the user selects a folder. That means the first time I select a folder for this session, a call to the server is made requesting the content of that folder. A call-back function is set which handles placing the data into the dataProvider and updating the view.

So far, so good. But there was a snag – to further optimise transferred data, we only return data about the images in the folder, not what folder they are in. So the call back function has no way of telling where to put the data unless we make sure that there’s only one call for folder contents at a time. Continue reading ‘Server result, who called?’

05
Mar
09

ErrorEvent – equivalent to throw new Error?

A technical question for you out there:

I had a class that dispatched an ErrorEvent which was not listened for by any other class. That resulted in the player popping up an error dialogue very similar to the one you get from throwing Errors – and not catching them.

Nice image – imagine a juggler throwing three or four Errors into the air and catching some of them.

The documentation for ErrorEvents says that ErrorEvents without listeners will be displayed by the debugger, but I can’t quite see how it’s handled. ErrorEvent inherits TextEvent, nothing special there. I just wonder how the flashPlayer detects these events. Is there hard coded special handling of Errors? Or are there attributes of the ErrorEvent that tells the player to treat it differently from other events?

File under “unecessary fidling with the API”

23
Feb
09

Web Services are suprisingly easy with Flex

Last time I had to work with web services, ActionScript2 was still hot stuff. Handling complex data was an absolute pain, mainly because of the woefully primitive XML implementation of AS2. Manually looping through children’s lists is not my idea of fulfilling programming tasks. Not that I realised how bad it was until AS3 showed up with E4X. “You mean I can just read the XML like an object or array? No way, that’s sci-fi!”

It was with a great deal of apprehension that I started on a new project that required integration with an external web service. But it turned out to be an absolute breeze. A small, hitherto ignored, menu item called “Data: Import Web Service (WSDL)” turned out to be very close to magic and became my new best friend.

Import Web Service takes an URI to the WSDL (web service definition language), loads and parses it and then lets you choose the methods you want to generate code for. It creates complete proxies with typed data classes for both in- and output. You can reload and regenerate classes if the web service changes, and you can add and remove methods at any time. All the generated code is accessible and well documented – although all is well documented with examples in the Flex help, I didn’t need more than the comments in the generated code.

I’m not claiming to have made a big discovery here, after all it’s part of the standard Flex Builder. But it just works so much better than I expected. Web Services have gone from being a royal pain to the easiest and most structured way of communicating with the server.

17
Feb
09

Dynamic classes for settings objects

Sometimes real world programming requires solutions that aren’t lovely  OOP-type code. For instance if you have a base class that is extended by a number of children, it’s not always possible to foresee all the types of arguments you need to send them, but you still need to define an interface.

In old-school AS2 code, we often used untyped objects as parameters for constructors. Bad OOP, but as AS2 doesn’t have typing, and the editor we used (SEPY) didn’t show us the arguments for methods and constructors, the code was more readable that way.

In AS3, classes are sealed by default, meaning that no attributes or methods can be added at run-time. This saves memory and increases performance. If you set a class as dynamic, it behaves like classes did in AS2 – you can add whatever you like at run-time.

We found that a variant of this AS2 technique was handy for those indeterminate settings objects. But instead of just passing a generic Object, we can create a dynamic class and define the settings that the base class uses and have those typed strictly. And we still allow future implementations to add their parameters. The downside of dynamic classes is that they use more memory than sealed (default) classes. But as they only live for a short time, it’s not a big real-world problem.

An example class from our framework. Notice the ‘dynamic’ declaration before ‘class’.

canDelete, pageStyle and pageLinkedToNextCount are types and cannot be set with other types. The parseRaw method is a way to take a generic object and insert all its attributes into this class.

package no.papirfly.msp.ptp.templates
{
    /**
     * Defined pageTypeSettings as used in <code>BaseTemplate.initPageTypes</code>
     * @param canDelete user can delete page. Default is false
     * @param pageStyle
     * @param pageLinkedToNextCount how many pages will be locked to this. 1 = next page is locked to this.package no.papirfly.msp.ptp.templates
     *
     */
    public dynamic class PageTypeSettings
    {
        public var canDelete:Boolean
        public var pageStyle:int
        public var pageLinkedToNexCount:uint;

        public function PageTypeSettings(canDelete:Boolean = false, pageStyle:int = 0, pageLinkedToNexCount:uint = 0)
        {
            this.canDelete = canDelete
            this.pageStyle = pageStyle
            this.pageLinkedToNexCount = pageLinkedToNexCount
        }
       /**        @private         */
        public function parseRaw(o:Object):void {
            for (var item:String in o) {
                this[item] = o[item];
            }
            if (o.canDelete == null) canDelete = false
        }
    }
}

We can instantiate this class:

var mySettings:PageTypeSettings = new PageTypeSettings(true);

and add new attributes that aren’t declared in the class:

mySettings.specialColorForMyPage = 0xFF00FF;

We lose strict typing, but it’s manageable when you use it for a few classes. If needed, the PageTypeSettings could be extended to type more attributes.

21
Nov
08

Tweening trouble

We had an odd problem in our new framework. We’ve centralized tween instantiation to a TweenManager class, a practical way to instantiate tweens without having to type the whole code shebang every time. It looked good, but after a while we noticed that sometimes the tween never finished properly. More research showed that it didn’t fire its TWEEN_END event. And it happened without any clear pattern. Some projects’ tweens worked ok, others not. Some worked one day, not the next. A debugging nightmare.

A bit of searching online showed that we weren’t the only ones experiencing this. The reason was that we assigned the tweens to variables within a function. As there was no other reference to it, it was eligible for garbage collection. And the flash player’s garbage collection happens when it wants. So sometimes the tween would be garbage collected before it reached the end and no event was fired.

It was fairly easy to fix – we now store references to the tween in a Dictionary and delete them on TWEEN_END

old code:

    var t:Tween = new Tween(targ, prop, options.ease, targ[prop] ,value, secs, true);
        //add listener for end of tween
        t.addEventListener(TweenEvent.MOTION_FINISH, function():void {
            t.dispatchEvent(new Event(TWEEN_END));
        });

revised code – we store options in a dictionary to be able to do different operations on end (like hide after fade out)

    if (_myTweens == null) _myTweens = new Dictionary();
    var t:Tween = new Tween(targ, prop, options.ease, targ[prop], value, secs, true);
    _myTweens[t] = options;
    //add listener for end of tween
    t.addEventListener(TweenEvent.MOTION_FINISH, onMotionFinish);

and clean up references with.

    private function onMotionFinish(e:Event):void {
       var t:Tween = Tween(e.target);
       var options:Object = _myTweens[e.target]
       if (options.hideAfter) t.obj.visible = false;
       delete _myTweens[t]
    }
20
Oct
08

Tabbing and focus in browser problem

(short version: If nested DisplayContainers have a mix of tabChildren states, tabbing from a child at the bottom will yield unwanted results)

We’re porting our Print product from as2 to as3. In that process I had implemented tab navigation in a table element. This was a total nightmare – tab worked beautifully in the flash standalone player, but not in a browser. In both IE and Firefox, hitting tab would change focus to the addess bar of the browser.

Why why why? I read the documentation for the FocusManager as I suspected it had something to do with this – focusManager was a tricky beast in AS2. No answers, so I started reading the actual code in focusManager.as (kudos to Adobe for allowing us to view and debug in the mx.* source code). No answers there either, but a lot of interesting code.

Finally I decided that I needed a more controlled environment to check how the flashPlayer handles tabbing. I created a very simple actionScript project with two editable textFields. This revealed that FP will move focus with tab till it’s at what it perceives as the last element. The tabbing will move focus to the address bar. Next tab will move it back to the first tabbable element in the flash.

So far, so good. But this didn’t answer why I lost focus in my app on every tab. After more hair pulling, I suspected that the tabChildren attribute on DisplayContainer could influence tabbing. I created four Sprite instances, nested them and placed an editable textField at the bottom. Setting all Sprites to tabChildren true or false both gave the correct result, i.e. focus went to the next flash object, not to the browser. But (and this is the finale) if there was a mix of tabChildren=true, tabChildren=false and tabChildren=true, tabbing from textField would send focus to the address bar.  An order of true, true, false, false would work – it was the mix that gave the bug.

After that it was easy to just ensure that the whole chain of DisplayContainers above my textField had tabChildren set to true.