ActionScript, Flash, and Flex
Posts tagged ActionScript
BackgroundAlpha: Why contentBackgroundAlpha?
Jun 5th
Situation: I was working with the Spark (Flex4) TextArea component. I wanted the background to no longer be visible or just simply alpha set to zero. I expected I could set a stylesheet property backgroundAlpha to zero. However, that didn’t work and there wasn’t even a property on the component called that. I dug in the source to find it and realized it is really contentBackgroundAlpha. Why? I see borderAlpha and expect to follow the same convention! I do not see contentBorderAlpha.
Why break a convention?
Why use contentBackgroundAlpha when borderAlpha is present and there is not already a backgroundAlpha?!
Popularity: 22% [?]
Parsing Algorithms – Creational Patterns
Mar 27th
This is as much a recommendation as a rant, so pardon me while I do both
Situation
Open-source project or foundational classes for use within your organization that contains methods for parsing data.
Background
Often, I’ve run into issues where I am using an open-source library (public or private) and I need to add extra logic to a creational algorithm(s) and cannot or cannot easily do so. This is what has sparked me to write this post, because I am increasingly seeing these types of issues.
Recommendation
When creating algorithms that create objects from other objects (eg models and serialization) , please use offload the logic to accessible and easily modifiable methods. In Design Pattern terms, I’m requesting and ranting that the Factory Method Pattern, Strategy Pattern, or something similar be used. This only compounds in importance when there are several objects created in a single method! <– That right there is arguably bad practice in general for large projects.
Example
NOTE: Showing a simple example seems to not show the problem, but I’ll try. For a better example, please refer to “Real-Life Example” below.
Mapping XML properties to models within a project.
protected updateList():void
{
var header:Header = new Header;
header.title = _xml.header.@title;
header.lang = _xml.header.@lang;
header.colors = _xml.header.colors.toArray();
var body:Body = _body;
var child:XML;
for (var i:Number = 0; i < _xml.body.item.length(); ++i)
{
child = _xml.body.item[i];
body.getItemAt(i).text = child.@text;
}
}
Real-Life Example
NOTE: I do not mean to pick on or criticize the fine work done by the peeps working on the OpenVideoPlayer Project and MUST EMPHASIZE that the project is very useful and saves time. This merely serves as an easy example to show. Moreover, I’ve written my fair share of problematic code along these lines too.
Popularity: 11% [?]
Tween Library Preferences and Strategy Patterns
Jan 17th
Problem:
When it comes to Tween libraries, it’s either a project’s requirements and/or developer personal preferences that can conflict in selecting a library. Honestly, the library shouldn’t matter. The importance is that the objects are tweened. This is especially important when it comes to open-source projects, as the issue only compounds where it’s much more likely that both personal preferences and project requirements will both be the issue with the open-source project.
Solution: Use the Strategy Pattern
Example (real-life example): Duncan Reid created a ToolTip UI class for ActionScript3. The problem I ran into was that fl.transitions.Tween was being used and I was working on an AS3 application that is using the now Greensock’s TweenLite. The solution that Duncan and I discussed was to use a Strategy Pattern to decouple the Tween library from the ToolTip class itself and offload the reference onto implementation. In other words, by utilizing the Strategy Pattern, it allows the developer to decide which tweening library he/she would prefer to use. For Duncan Reid’s ToolTip UI I did the following:
- Added New Files:
- com.hybrid.ui.strategies.IToolTipTweenStrategy
- com.hybrid.ui.strategies.ToolTipTweenStrategy – The only place where fl.transitions.Tween is being used/referenced
- ToolTip now has a required constructor parameter tweenStrategy which will accept anything implementing the IToolTipTweenStrategy
This now means that the ToolTip UI class depends on one thing – the Tween Strategy. In fact, the strategy could be set to null (not given to the ToolTip), then no tweening would take place. Instead, the tooltip would just display or hide immediately. As such, the required construction param could be made optional (ie default set to null).
In action this simply looks like
new ToolTip(new com.hybrid.ui.strategies.ToolTipTweenStrategy)
//OR
new ToolTip(new com.novelastudios.ui.strategies.ToolTipTweenStrategy)
Source Files / Source Examples (using Duncan Reid’s ToolTip UI)
- Example of dynamic strategy changing ( visual demo / source )
- Click the Radio Buttons at the top of the visual demo to switch between the different strategies.
- Implementing it into Duncan’s original example
- Using fl.transitions.Tween ( visual demo / source .fla | .as )
- Using com.greensocks.TweenLite ( visual demo / source .fla | .as )
Note
The above source is not officially supported / maintained by Duncan Reid and as such I recommend that this simply be used as an example and refer you to his site and source code for production use.
Additional Information
For more information on the Strategy Pattern with ActionScript3 checkout the following:
Popularity: 100% [?]
Invoking Constructors
Nov 26th
RJ Regenold and I were discussing last night how we both strongly believe constructors should have extremely limited algorithms that simply invoke protected methods.
For instance, PureMVC’s Facade initializes the instance in the constructor
package org.puremvc.as3.multicore.patterns.facade
{
import org.puremvc.as3.multicore.core.*;
import org.puremvc.as3.multicore.interfaces.*;
import org.puremvc.as3.multicore.patterns.observer.*;
public function Facade( key:String )
{
if (instanceMap[ key ] != null) throw Error(MULTITON_MSG);
initializeNotifier( key );
instanceMap[ multitonKey ] = this;
initializeFacade();
}
}
package org.puremvc.as3.multicore.patterns.facade
{
import org.puremvc.as3.multicore.core.*;
import org.puremvc.as3.multicore.interfaces.*;
import org.puremvc.as3.multicore.patterns.observer.*;
public function Facade( key:String )
{
if (instanceMap[ key ] != null) throw Error(MULTITON_MSG);
initializeNotifier( key );
initializeInstance();
initializeFacade();
}
protected function initializeInstance():void
{
instanceMap[ multitonKey ] = this;
}
}
I would even argue that the Error checking / validation takes place in an init of some kind as well.
Another example is as follows
Instead of doing,
package
{
import flash.display.Sprite;
public class ViewUI extends Sprite
{
public function ViewUI()
{
super();
width = 100;
height = 200;
}
}
}
Do this
package
{
import flash.display.Sprite;
public class ViewUI extends Sprite
{
public function ViewUI()
{
super();
init();
}
protected function init():void
{
width = 100;
height = 200;
}
}
}
This practice becomes increasingly important in open-source projects. Moreover, this example may be limited but consider more complex constructors that you’ve seen or written yourself. The construction process should be divided into segments when possible.
UPDATE ( 01.13.10 ): Bill Sanders recently posted a good article about this exact topic!
Popularity: 23% [?]
Serialize/Clone Objects (Bug with Required Constructor Params)
Oct 6th
My opinion is that the following is a big bug.
When serializing/cloning an object that has required constructor parameters, you receive an error telling you the arguments are incorrect. Note: the following is just an example using a “native” flash class. Really, you should never have to serialize or clone an Event, so please just see it as an example class as the type of class isn’t the point.
import flash.net.registerClassAlias;
import flash.events.Event;
import mx.utils.ObjectUtil;
flash.net.registerClassAlias("flash.events.Event",Event);
var event:Event = new Event(Event.CHANGE);
var eventClone:* = ObjectUtil.copy(event);
trace(eventClone is Event)
RESULT
ArgumentError: Error #1063: Argument count mismatch on flash.events::Event(). Expected 1, got 0.
at flash.utils::ByteArray/readObject()
at mx.utils::ObjectUtil$/copy()
at Untitled_fla::MainTimeline/frame1()
As noted by Nutrox, “All constructor parameters need a default value. You can’t pass values directly to an object’s constructor when it is restored from serialised data because Flash creates an instance of the object automatically before calling the object’s readExternal() method.”
What are your thoughts? I’m interested in striking a conversation about this.
Popularity: 43% [?]
DisplayObject.scrollRect dimension reporting workaround
Jun 27th
I came across a bug where when you set the scrollRect of a DisplayObject and get a dimension, within the first few mil/nano-seconds it reports the correct width and height. However, after that the reported width and height is the scrollRect‘s width and height. This to me is a bug considering you can not request the object to tell you it’s full dimensions any longer.
Take a look at http://www.kirupa.com/forum/archive/index.php/t-256884.html and here is the solution http://usecake.com/lab/find-the-height-and-width-of-a-sprite-with-a-scrollrect.html
Popularity: 37% [?]
Most Recent Comments