connectedpixel.com

actionscript, web development

Component Array Parameter Gotcha

Submitted by joelmay on 22 November, 2005 - 11:18am.

So the other day, I was working on a component that has an inspectable set/get array property. I could not get it work. Although the default value for this array was not zero length and the parameter in the dialog box was not zero length, the set function was being called with a zero-length array at initialization.

This was an invalid situation and broke my app.

Here's a simplified version of the code:

class Thing extends MovieClip {
 
  private var _myArr:Array;

  ... other code here ...

  [Inspectable(defaultValue=[0,255],type="Array"]
  public function set stuff(ar:Array):Void {
    if (ar.length == 0){
      trace("Invalid param.  Array is zero len");
      return;
    }
    // Make a copy of the input array using concat. 
    // Don't want outside code to have a reference 
    // to a private data member.
    _myArr = ar.concat();
    updateDisplay();
  }
  // Again, return a copy of the array so that
  // outside code cannot alter the
  // internals of this component directly.
  public function get stuff():Array { 
    return _myArr.concat(); 
  }
}

Notice that I'm trying to be a good programmer here:

  • I verify the array argument is valid before using it.
  • I don't let code external to this class have a reference to the array data member (I make copies of the array going in and out). This prevents external code from changing the component's guts unbeknownst to the component itself.

In desperation, I decompiled my swf with ASV. I wanted to know how the flash player passes the component dialog box parameters to the component. With the "stuff" parameter set to [45,17,255] in the component property dialog box, here's what I expected:

myThing.stuff = [45,17,255];

But here's what I found:

myThing.stuff = [];
myThing.stuff[0] = 45;
myThing.stuff[1] = 17;
myThing.stuff[2] = 255;

Exercise for the reader: Figure out why my trying to be a "good" programmer was a bad idea.

caseyc (not verified) Says:

Components

22 November, 2005 - 2:27pm

I don't use getter/setters for [Inspectable] component parameters, in fact I try to keep them as simple as possible. You have to remember that inspectable params will be set before your class has initialized so you can run into all kinds of problems. Your best bet is to use simple params and onUpdate for live preview (you have to create a compiled clip) and then set your properties manually after initialization, something like this:

class Thing extends MovieClip
{
[Inspectable(name="My Array",defaultValue="0,255")]
private var cp_dataArray:Array;

private var m_dataArray:Array;

public function set dataArray( p_dataArray )
{
m_dataArray = p_dataArray.slice();
}

public function get dataArray()
{
return m_dataArray.slice();
}

private function onUpdate()
{
trace("Array changed: "+cp_dataArray);
}

private function onLoad()
{
dataArray = cp_dataArray;
trace(dataArray);
}
}

joelmay Says:

Good idea

22 November, 2005 - 3:20pm

By putting the [Inspectable] on a private data member, I don't have to worry about exposing my component's internals. The private data member is only exposed to under-the-hood initialization code.

The setter/getters are still set up to prevent exposing the component's insides.

Makes sense.

Thanks,
Joel

Darren (not verified) Says:

Meta Tags

15 August, 2007 - 11:36am

Hello,

I just figured out the whole process for creating FlashCS3 components but for the life of me can't seem to find the supported meta tags that can be used. Does anyone have docs on this?

Thanks,

D