Strangeness in custom component parameters

Leave a comment

I decided today to systematically analyse a problem that’s bothered me for several years: What determines whether a parameter setter for a custom component will be called?

Today I’ve finally worked it out, and discovered that my lack of clarity was justified…

So I have a simple custom component with one Number parameter:

package  {

     import flash.display.MovieClip;
     import flash.events.Event;

     public class CustomComponent extends MovieClip {

          private var _aNumber:int;
          [Inspectable (type="Number")]
          public function get aNumber():int {return _aNumber;}
          public function set aNumber(value:int):void {
               trace("set number "+value);
               _aNumber = value;
          }

          public function CustomComponent() {
               loaderInfo.addEventListener(Event.INIT, onInit);
          }
          private function onInit(event:Event):void {
               trace("aNumber="+aNumber);
          }
     }
}

This gives the parameter aNumber:

Now when this parameter is set to ’1′, and we test the movie, we see the following trace:

set number 1
aNumber=1

When this parameter is set to ’0′ we see the following:

aNumber=0

So the INIT event is still dispatched, but the parameter setter is NOT called! Why? My hypothesis is that it’s not called as it is the same as the default value for the parameter. To test this hypothesis, I change the default for the variable:

          [Inspectable (type="Number",defaultValue=100)]

Now, with the parameter set to ’0′ the trace is:

set number 0
aNumber=0

So obviously the default does affect whether the setter is called. It appears as though:

  • if the defaultValue and the parameter values are the same, the parameter setter is not called.
  • if the defaultValue and the parameter values are different, the parameter setter is called.

BUT – so far we’ve only looked at ONE parameter, what if there are several? this is where the plot gets thicker!

I’ve added two additional parameters to my custom component, a String, and a Boolean:

package  {

     import flash.display.MovieClip;
     import flash.events.Event;

     public class CustomComponent extends MovieClip {

          private var _aBoolean:Boolean;
          [Inspectable (type="Boolean")]
          public function get aBoolean():Boolean {return _aBoolean;}
          public function set aBoolean(value:Boolean):void {
               trace("set boolean "+value);
               _aBoolean = value;
          }

          private var _aNumber:int;
          [Inspectable (type="Number")]
          public function get aNumber():int {return _aNumber;}
          public function set aNumber(value:int):void {
               trace("set number "+value);
               _aNumber = value;
          }

          private var _aString:String;
          [Inspectable (type="String")]
          public function get aString():String {return _aString;}
          public function set aString(value:String):void {
               trace("set string "+value);
               _aString = value;
          }

          public function CustomComponent() {
               loaderInfo.addEventListener(Event.INIT, onInit);
          }
          private function onInit(event:Event):void {
               trace("aNumber="+aNumber+", aString="+aString+", aBoolean="+aBoolean);
          }
     }
}

Now we have three parameters:


If we leave the three parameters with their defaults, we only see the trace from the constructor:

aNumber=0, aString=null, aBoolean=false

But if we change just one parameter, in addition to the constructor trace, we see the trace from all three parameter setters:

set boolean true
set number 0
set string
aNumber=0, aString=, aBoolean=true

So, long story short, the custom component rule of strangeness breaks down to the following:

  • If none of the parameters are different to their defaults, none of the parameter setters run.
  • If JUST ONE of the parameters is different to the default, ALL of the parameter setters run.

strrrange…

Captivate error loop on unload

Leave a comment

Obviously I’m working a bit with captivate files lately, my last three posts have been about the joys of using them.

My latest problem is that when I request a Loader object to unload a captivate generated swf, I immediately get a series of never-ending errors, that repeats the same thing:

TypeError: Error #1009: Cannot access a property or method of a null object reference.     
at captivate.veela_as3::rdSwfLoader/IsParentSlidelet()     
at captivate.veela_as3::rdItem/getParentCurrFrame()     
at captivate.veela_as3::rdSwfLoader/getParentCurrFrame()     
at captivate.veela_as3::rdSwfLoader/rdSwfLoaderEnterFrame()

If I was permitted to use FlashPlayer 10 in this project I would probably try unloadAndStop() or if that didn’t work, uncaughtErrorEvents, but unfortunately this project requires Flash player 9. Nothing worked in attempting to prevent this error.

In the end I just commented out the line:

loader.unload();

and instead just removeChild(loader) and set loader to null. For some reason the Captivate swf spits the dummy if it doesn’t have a parent.

What a baby.

Solved! The mystery of the captivate ghosts…

Leave a comment

I was finding that all of my swfs exported from Captivate, contained slight blurriness, and left stray artifacts and ghosting on transitions. Why oh why… It was only occurring on PCs and only when loaded into the main projector. And yet when I setup an alternative loader.fla the blur and artifacts were gone! There had to be a reason. After some time eliminating causes, I’ve found the cause, one line of code. Which to be honest I’m still not sure why it would be causing the problem, but it does:

stage.showDefaultContextMenu = false;

Fortunately it’s not such a big deal to remove this line, so. Problem solved. Wins most obscure bug solution of the year though.

Captivate communicating with Flash

Leave a comment

I think it’s a little strange that Captivate is owned by the same company as Flash and exports ‘swf’ format, yet there’s no option to simply dispatch a Flash event. Which makes communication between a Flash holder and the Captivate movie problematic.

There are a few solutions(i.e. hacks!) out there:

  1. Import a flash movie on the final frame of the movie, which contains the actionscript that we wanted to execute, perhaps by calling a function on the root…
  2. pipwerks blog had a very interesting lateral thinking solution: Captivate actually permits you to call a javascript function. Flash can be listening to this function with a callback.

I found both of these methods with their drawbacks in their own ways.

Solution 1 has potential scope issues, that the child Flash movie would have to know exactly the path to call the function, and could easily be problematic once we start incorporating preloaders.

Solution 2 (Captivate->HTML[Javascript]->Flash communication). Although a neat solution, I always try to avoid this sort of thing if possible just to avoid the possibility of browser / cross-platform issues, etc.

I was looking at other possibilities within Captivate and discovered that one Flash-esque thing that Captivate can do, is set a variable. I realized that quite a simple and neat solution was possible:

After loading the Captivate file, the parent Flash file can be constantly checking if the Captivate file has set the variable (on enter frame) and when it has, trigger an action.

This is easily accessed. I had a variable called ‘completed’, and I checked it via:

loader.content.completed

My Review of Introducing Starling

Leave a comment

Originally submitted at O’Reilly

Building GPU Accelerated Applications

Great intro to Starling, but not perfect

By craiggrummitt from Melbourne, Australia on 1/22/2012
4out of 5

Pros: Easy to understand, Helpful examples

Cons: Too many errors

Best Uses: Expert

Describe Yourself: Developer

A great introduction to Starling, well structured, well explained and contains comprehensive examples.

The only major drawback is there are obvious editorial issues in the text and bugs/errors in the code examples.

But – it’s free, so I’m not complaining. It’s an invaluable read if you’re interested in this new framework.

(legalese)

Two FLVPlayers battle eachother with full-screen

Leave a comment

When an FLVPlayer component contains a fullscreen button, whenever the application goes to full-screen, the component automatically shows the FLVPlayer component, even if you have set up an alternative full-screen button elsewhere. The way to prevent the component from hijacking fullscreen operations is by setting the ‘fullScreenTakeOver’ property to false:
video.fullScreenTakeOver=false;

However, when the user clicks fullscreen on the video component itself, you probably want the video to resize so when your video is relevant, don’t forget to set this property back to true.

The interesting thing is that when there are two videos in an application, only one of them wins out as the dominant take-over component, so therefore when you click full-screen on the other component, you actually see the dominant player’s video go full-screen. So, when you have two FLVPlayers in different sections, be sure that only the current FLVPlayer has ‘fullScreenTakeOver’ set to true.

Warning: All instances will be automatically declared as…

Leave a comment

Sometimes it’s useful to have two Flash symbols which use the same Base Class which references symbols within the clip, that could be differently symbols. For example, a symbol of base class ‘Menu’ could contains symbols, of base class ‘menuItem’. You might want this to occur in two symbols, ‘MainMenu’ and ‘SubMenu’ which reuse the same ‘Menu’ class for reuse, because they contain exactly the same functionality.i.e.:

the movieClip MainMenu, has the base class Menu

the movieClip SubMenu has the base class Menu

However, you’ll encounter a warning:

Warning: All instances named ‘xxx’ will be automatically declared as xxx in symbols that use xxx as their base class. In symbols that are linked to user-defined base classes, instances with the same name must be of the same type.

In our example, all items called ‘menuItem1′ within the ‘menu’ class will all be visually the same, because their class is assumed to be the same.

Now googling this problem seems to result in only one possible solution, to uncheck ‘Automatically declare stage instances’ in the advanced actionscript 3.0 settings, but really this makes life more difficult in other areas. There are also calls for Adobe to automatically declare instances as the base class rather than the super class, but I believe this would introduce other problems, as the symbols contained in the superclass would not be available.

My solution is probably obvious to some, but here it is. To avoid Flash automatically declaring the instance as the superclass and therefore typing all symbols the same, we just need to create a simple unique base class for each unique symbol that extends our class. This is a little confusing to explain, so to return to the example:

the symbol MainMenu, has the base class MainMenu, which just extends the ‘Menu’ class.

the symbol SubMenu, has the base class SubMenu, which just extends the ‘Menu’ class.

This way the menu items are not automatically typed to be the same symbol.

Facebook Flash app lessons…

Leave a comment

Been building a few Facebook Flash apps lately, and learnt some lessons on the way, some that didn’t appear to be in manuals, or are easy to skip over and then find yourself problem-solving…

  • Your Flash object has to be set to wmode=transparent so that it plays nicely with z-indexes.
  • If you’re loading images from Facebook, you need to load a security policy file. eg:

Security.loadPolicyFile(“https://graph.facebook.com/crossdomain.xml”);

SCORM with custom menu built in Flash

7 Comments

I’ve been researching into making a training course SCORM compliant. Been quite a learning curve, and to be honest the whole system seems quite outdated and excessively jargon rich. Reading the documentation is like trying to swim laps in a swamp…

ADL(responsible for SCORM) have built a javascript library(libscorm) that works with the latest version of SCORM(ironically called 2004), and can also be called from Flash.

I was tasked with the challenge of retaining the course as it was with a custom menu within Flash. I encountered problems trying to consolidate the idea of a custom menu within Flash with the concept of SCO’s.

There are ways described out there: (see here for a pure html solution) but there still seems to me to be less flexibility.

I was directed to the examples built by Philip Hutchison, which was an interesting take on the problem. He says in his blog:

In my opinion, SCORM only becomes difficult if you try and use it to handle a course’s sequencing and navigation, which even SCORM experts are hesitant to do (it’s considered a “broken” feature by many key figures in the industry).

What he is saying, and the elegant solution he proposed in a nutshell, was to build the system into just one SCO and use the perpetual data variable ‘suspend_data’ to record status information about modules within the course.

This works well, however there are some problems with his source:
1. It uses an old version of SCORM (1.2)

2. It uses a pipwerks javacript wrapper, which is great, but I fear as it’s a 3rd party product may not be maintained as new versions of SCORM come out, and may be more limited in functionality than the ADL developed LibScorm.

3. The Flash coding is a little strange(sorry Philip), using an include statement rather than an application class, something I haven’t seen since AS2.

So I took on the challenge to build a proof of concept example that addresses and resolves these three points. Download a zip file here that contains the source and SCORM ZIP package. It uses:

  1. SCORM 2004 Fourth edition
  2. the ADL developed javascript library LibScorm

Video white

Leave a comment

A recent task I had to achieve was to play a video for several seconds and extract a frame as a JPG several seconds in. I did not know the dimensions of the video ahead of time, so hoped to extract that information out of the video metadata, and create the video object at this point. Sounds simple enough!

However, this only seemed to work about 75% of the time. Occasionally I was seeing just white in certain videos, like they weren’t attached correctly to the Video object(despite receiving the metadata correctly). My theory was that perhaps the metadata was received after the FLV began playing, and that perhaps there can be problems creating a Video object and attaching a NetStream to it, after it has begun playing.

So I tried creating the Video object and then resizing after receiving the FLV metadata, but the resize seemed to have no effect when extracting the Bitmap Data. But finally found a solution – the Bitmap Data extracted correctly, if I placed the Video object inside a MovieClip and extracted the Bitmap Data of the MovieClip instead of the resized Video object.

Older Entries

Follow

Get every new post delivered to your Inbox.