Introducing Reflex

It occurred to me that I haven’t even posted about what Reflex is yet. So here is a quick overview. Reflex is a component framework. Like Flex, it is a methodology and some base classes on which to build components. Unlike other component sets, it is not just a component set but a framework to build components. It can be coded with MXML. It has layout, skins, and run-time added behaviors. It keeps close to the Flash player APIs so mixing with Sprites, MovieClips, and TextFields is a non-issue. It works in the Flash IDE as well as Flash Builder. And it’s just getting going. The git repo is at http://github.com/reflex/. The mailing list/forum is at http://groups.google.com/group/reflex-platform. We have plans for styling support, states, and all the other great feature that Flex provides. The reason we’re starting a new project and not contributing to Flex is because we felt it was necessary to start from scratch in order to accomplish what we want to. We hope to provide a compelling alternative to Flex that is smaller, faster, and easier to build on top of. We admire the Flex team at Adobe and acknowledge that we couldn’t do what we are without the trail that they’ve blazed. We hope

pharmacy7days-onlineother meds herehttp://pharmacy-online-24hour.com/flonase-online.htmlhttp://pharmacy-online-24hour.com/parlodel-online.htmllasix cost

to get a website up soon. We’ll have unit testing and continuous builds. We generally are striving to do everything right and keep up the momentum. Tyler and I presented at 360|Flex on Reflex and posted about the presentation demos. I also just posted about how to build behaviors in Reflex. So if you didn’t know, Reflex is the next big thing (I hope). :) We hope you’ll participate on the mailing list and help contribute to the project.

How To Build a Behavior in Reflex

Update: If you don’t know what Reflex is, I’ve just introduced Reflex.

Building a component in Reflex consists of 3 things: making the component class, building the behaviors, and creating the skin. The component class is an extension of Component with your new component’s name and a few public properties that you feel might be important to that type of component. The real logic of the component goes into its behaviors, so that is where we are starting today.

What is a Behavior?

A behavior is a well defined piece of functionality that may be used by one or more components. Behaviors do not necessarily map directly to a component type. Sometimes they are planned and sometimes they are refactored into separate pieces for reuse. For example, in Reflex the ScrollBar uses a ScrollBehavior and a StepBehavior. Because the scroll bar’s data is similar to a numeric stepper, and because the buttons on a numeric stepper and a scroll bar have the same behavior, ScrollBehavior was broken down into a ScrollBehavior which handles track clicking and dragging the thumb, and a StepBehavior which handles clicking the up/down buttons.

Behaviors are made up of a target, data, skin parts, and event listeners. The target is defined on the base Behavior class and will get set automatically. The data is any properties that a behavior needs in order to function. It maps to the properties on the component that relate to this particular behavior and are bound to the target’s equivalent data. And listeners are set up to respond to the events on the component and parts of the skin. Behaviors make heavy use of data binding to wire everything together, reducing complexity and wiring code. This is one reason why optimizing data binding has been such a big focus for us.

Note that Reflex does not follow a purist MVC approach. Behaviors consist of the controller (“C” in MVC) functionality as well as duplicating the model (“M” in MVC) data. This allows our pieces to work independently with the added benefit of allowing simple Sprite’s and MovieClip’s to become components by virtue of the behaviors that target them. They don’t need to be a scroll bar in order to work like one.

Building a Behavior

We will use an example to build our behavior. Let’s say we have a button component, and we want it to vibrate when you click on it when it is disabled. Sort of a “no no, don’t do that” thing. Guess what, we don’t need to extend Button or even ButtonBehavior to do this. Avoid extending old functionality when adding new functionality. In fact, avoid extending as much as possible in Reflex except for the base classes. We want to stay away from inheritance trees.

First we create our DisabledBuzzBehavior class, extending Behavior to give us our target property and a couple of unnecessary but nice helper methods.

Then we want to add our data. The only thing we need to know about is whether the button is enabled or disabled. We don’t care what the label is or whether the button is selected (like checkbox or radio button). So at the top of the class add a bindable disabled property.

public class DisabledBuzzBehavior extends Behavior
{
	[Bindable]
	public var disabled:Boolean;

	public function DisabledBuzzBehavior(target:InteractiveObject=null)
	{
		super(target);
	}
}

We want our disabled property to always be the same as the component’s (or target’s) disabled property, so we will start setting up our bindings. We can do this in the constructor and use the little helper methods.

public function DisabledBuzzBehavior(target:InteractiveObject=null)
{
	super(target);
	bindProperty("disabled", "target.disabled");
}

Next we want to know whenever the component is clicked. We could override the target setter to add and remove listeners whenever it is set or unset, but we have binding methods for that too which is better.

public function DisabledBuzzBehavior(target:InteractiveObject=null)
{
	super(target);
	bindProperty("disabled", "target.disabled");
	bindEventListener(MouseEvent.CLICK, onClick, "target");
}

private function onClick(event:MouseEvent):void
{
}

Note that in Reflex we don’t worry so much about making everything “protected” because instead of subclassing everything you can simply replace it with your own version. Logic is broken up enough that you don’t have to make everything protected unless you know someone will want to subclass your behavior.

Now all we have to do is add the logic to our onClick method. This is stuff that isn’t Reflex specific and you will be determining on your own for your behaviors.

private var count:int;
private var originalX:Number;
private var intensity:Number = 4;

private function onClick(event:MouseEvent):void
{
	if (!disabled) return; // only react if we're disabled

	count = 0;
	originalX = target.x; // assuming if we got a click that target isn't null
	target.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

private function onEnterFrame(event:Event):void
{
	if (target == null) {
		// the behavior was removed in the middle of it's thing
		event.target.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
	} else if (count >= 12) {
		target.x = originalX;
		target.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
	} else if (count++ % 2) {
		target.x = originalX + intensity;
	} else {
		target.x = originalX - intensity;
	}
}

You can see that we may need to store additional information other than the component data in order to get our job done. But this doesn’t need to be public API or bindable. You can also see that I’m trying to account for any situations that might break the code to make my behavior as solid as possible (e.g. checking to see if target is still set on each enter frame).

The whole behavior looks like this:

public class DisabledBuzzBehavior extends Behavior
{
	[Bindable]
	public var disabled:Boolean;

	private var count:int;
	private var originalX:Number;
	private var intensity:Number = 4;

	public function DisabledBuzzBehavior(target:InteractiveObject=null)
	{
		super(target);
		bindProperty("disabled", "target.disabled");
		bindEventListener(MouseEvent.CLICK, onClick, "target");
	}

	private function onClick(event:MouseEvent):void
	{
		if (!disabled) return; // only react if we're disabled

		count = 0;
		originalX = target.x; // assuming if we got a click that target isn't null
		target.addEventListener(Event.ENTER_FRAME, onEnterFrame);
	}

	private function onEnterFrame(event:Event):void
	{
		if (target == null) {
			// the behavior was removed in the middle of it's thing
			event.target.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
		} else if (count >= 12) {
			target.x = originalX;
			target.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
		} else if (count++ % 2) {
			target.x = originalX + intensity;
		} else {
			target.x = originalX - intensity;
		}
	}
}

Update: The following is how you would do the same with metadata.

public class DisabledBuzzBehavior extends Behavior
{
	[Bindable]
	[Binding(target="target.disabled")]
	public var disabled:Boolean;

	private var count:int;
	private var originalX:Number;
	private var intensity:Number = 4;

	[EventListener(type="click", target="target")]
	public function onClick(event:MouseEvent):void
	{
		if (!disabled) return; // only react if we're disabled

		count = 0;
		originalX = target.x; // assuming if we got a click that target isn't null
		target.addEventListener(Event.ENTER_FRAME, onEnterFrame);
	}

	private function onEnterFrame(event:Event):void
	{
		if (target == null) {
			// the behavior was removed in the middle of it's thing
			event.target.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
		} else if (count >= 12) {
			target.x = originalX;
			target.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
		} else if (count++ % 2) {
			target.x = originalX + intensity;
		} else {
			target.x = originalX - intensity;
		}
	}
}

and can be added at runtime to a certain button or to all buttons by adding it to the stylesheet.

<rx:Button>
	<rx:behaviors>
		<rx:ButtonBehavior/>
		<behaviors:DisabledBuzzBehavior/>
	</rx:behaviors>
</rx:Button>

or

Button behaviors {
	button: ClassReference("reflex.skins.ButtonBehavior");
	disabledBuzz: ClassReference("my.behaviors.DisabledBuzzBehavior");
}

More about the weird CSS in a later post. And the skin parts hookup is still under review, so I didn’t include an example with that workflow yet until we have it solidified.

So now you can start building out behaviors without any skins or components. You have everything you need right inside a behavior.

Reflex Demos

At 360|Flex we showed some pretty cool demos. The coolest one Tyler made and is on his blog, so go check out the Phases of the Moon there. Here are some you can right-click to view the source.

We have some examples of how skins and behaviors can be swapped out:

And a demonstration of how behaviors can work with any Flash display objects (including Flex ones in this case):

Enjoy!

Update: Oh, and here are the slides.

Simple Object Pooling in Flash

Been loving 360 Flex this year! Tyler and I finally finished our presentation, and so I had some time to write a post I’ve been meaning to.

One of the issues one comes across in building performant applications in Flash is object creation and garbage collection. Object pooling helps overcome this. Object pooling is keeping old objects around and reusing them instead of throwing them away and always creating new fresh objects.

Creating objects in Flash isn’t bad. It’s when you create hundreds or thousands of throw-away objects very quickly that this becomes a problem.

Used Pooling in Observe

For my final implementation of the Observe class I use objects to temporarily store information about hooks and observers that allows me to sort them based on order they were added. At first I thought how unfortunate that I have to create objects to do this when one of the major reasons for creating Observe is to eliminate the creation of Event objects every time a property change happens.

Fortunately I have complete control over Observe and its implementation (unlike Flash’s Event model) and I can pool these temporary objects. Setting up pooling is very simple and I’d like to demonstrate how it can be done by pretending we’re building a super-fast memory efficient best-performance tween engine. We’ll go with this use case, build pooling, and let the remainder of the tween engine be left to the imagination or as an exercise of the reader to finish.

Tweening Ultra-Speed

Our pretend tween engine is called Tweening Ultra-Speed, because that sounds super cool. Super duper cool (k, so it’s late). The biggest problem with high-peformance tween engines like GreenSock’s preventing them from pushing beyond their top speeds even further is object creation and garbage-collection. In order to create a new tween the API might look like this:

Tween.create({target: mySprite, duration: 1000, x: 10, y: 20});

No big deal, right? Unless you’re pushing the limits and creating thousands of these every second. The object being created between those parentheses is being allocated some memory and then garbage collected later. Memory builds up as thousands of these are called, then drops back down (with a noticeable pause in the animation) because the garbage collection cleans up the old objects.

How else could we do this?

We need to have objects that we can reuse. We might go specific and have a MovementTween that holds the x/y properties. We might do a size tween that holds the width/height properties. I’m going to go with generic and do a property tween for each type of property. For now, we will cover 90% + of tween use-cases with a NumberTween object.

public final class NumberTween
{
	public var name:String;
	public var value:Number;
	
	public function NumberTween(name:String, value:Number)
	{
		this.name = name;
		this.value = value;
	}
}

I’m keeping it simple and not including other stuff we might need such as current value and delta value, easing, and stuff like that. Now we have a concrete object that would be used like so:

var tween:Tween = new Tween(mySprite, 1000); // let's say 1000 is the duration
tween.addProperty(new NumberTween("x", 10));
tween.addProperty(new NumberTween("y", 20));

Of course, this doesn’t solve the problem yet, but now that we have a concrete class, we can make a pool for NumberTweens. My favorite way is to add a static method on the class and using a link-list. It is very fast and light, and I think very elegant.

public final class NumberTween
{
	public var name:String;
	public var value:Number;
	public var next:NumberTween; // this is for the link-list. We can also use this outside the pool to link our tweens together in the addProperty calls.
	
	private static var pool:NumberTween;
	
	public static function get(name:String, value:Number):NumberTween
	{
		var tween:NumberTween = pool;
		if (tween == null) tween = new NumberTween();
		
		pool = tween.next;
		tween.next = null;
		tween.name = name;
		tween.value = value;
	}
	
	public static function put(tween:NumberTween):void
	{
		tween.next = pool;
		pool = tween.next;
	}
}

The important things to note here are the static get and put methods. You now use get to retrieve a new NumberTween instance and put to “release” it back to the pool once you’re done with it. If your pooled object points to any objects or non-mutable types (non-string/number/boolean) this could be where it gets cleaned up too (don’t keep mySprite tied in memory to a pooled Tween object). I’ve also made a method called destroy that does the same thing, puts it back into the pool. Let’s say we do something similar for our Tween class as well.

var tween:Tween = Tween.get(mySprite, 1000);
tween.addProperty(NumberTween.get("x", 10));
tween.addProperty(NumberTween.get("y", 20));

Once the tween has finished running it can call a Tween.put() on itself which might call property.constructor.put() on all of its properties. The great part for this particular scenario is that you can have NumberTween, ColorTween, BlurFilterTween, etc. for each type you want to support! Now we may be creating thousands of tweens every second but we’re recycling object instances so that object creation is limited and garbage collection isn’t slowing things down. What is it they say? “Reduce, reuse, recycle.”

This is my take on object pooling. You could create a pooling framework, but it is so simple to add pooling to a class, it doesn’t seem necessary for quick things. And this pooling would speed up tween engines that much more (at the expense of more lines of code to create a tween. There are trade-offs).

So who’s going to finish my tween engine for me?