Command locations

July 29th, 2008

Ted Naleid just gave me some handy info regarding command locations in *nix, which I’m sure I’ll want to reference again ;)

“whereis” is a little different than the “which” command. “whereis” looks in “standard” places for executables, places that are set up by default (i.e. not macports). “which” actually checks your currently active “PATH” for the first thing matching the string, so you know which item will actually get executed. I find “which” much more useful than “whereis”.

There’s also a “where” command that shows all locations in your path of an executable (in order of where they are in your path).

pollux% which svn
/opt/local/bin/svn

pollux% whereis svn
/usr/bin/svn

pollux% where svn
/opt/local/bin/svn
/usr/bin/svn

Alex Uhlmann: Using Binding Securely

July 18th, 2008

The following is a re-print of Alex Uhlmann’s post. I’ve only ‘reprinted’ it here, as the weblogs.macromedia.com site appears to be broken.
Original article

September 28, 2006

Using Binding Securely

In my last post about the Cairngorm Dashboard example I’ve added a little functionality that allowed a view to react to a state change in the model in order to do something view related like invoking a popup or an effect.

I’ve been using the binding approach and that made it very easy and flexible to do. But as I said in my last post, this can have one slight drawback you have to consider. In this post I’ll showcase the drawback and provide a solution to it via an extended version of Paul’s Observe tag. Furthermore, this extended version of Observe makes it even easier to perform this kind of listening to the model.

Behind the scenes, binding uses flash.events.EventDispatcher. But binding gives you much more than just that. You can bind to properties even when their objects aren’t initialized yet. You can also bind to XML data using E4X to specifically listen to certain areas of the XML. For more information on the features of binding make sure you read the Chapter 37 in Part 5 of the Flex 2 Developer’s Guide.

There are multiple ways to use binding. All of them require a source that defines what property you want to listen to and a destination that defines what shall be triggered once your source changes.
You can either use the MXML curly braces syntax, function binding, the mx:Binding tag or define bindings in ActionScript.

Either way, you have to be careful in triggering application code in a destination of a binding, which we’ve done in previous examples of my Dashboard sample using either function binding to trigger a formatter or mx:Binding to invoke a view related method.
Since the Binding feature hides us from many exceptions that would have been thrown using EventDispatcher, it cannot differentiate in certain situations when certain; to us important, exceptions are thrown in our application code that is triggered in the destination. Let’s showcase this and throw one of these “certain” exceptions on purpose in our latest Cairngorm Dashboard sample. Let’s throw one that I’m sure you’ve have seen before: The one and famous:

ErrorID 1009: “Cannot access a property or method of a null object reference.”

Change the createChargedMessage setter to:

private function set createChargedMessage( value : Boolean ) : void
{
        var o1 : Object = {};
	o1.o2 = {};
	trace( "show o2 " + o1.o2 );
	o1.o2 = null;
	o1.o2.foo = "bar"; //oops, o2 doesn't exist, an exception should be thrown.
	trace( "show foo " + o1.o2.foo );
	if( value ) Alert.show( "Thanks! Your bank account has been charged" );
}

Since this code is triggered as a destination of the mx:Binding tag, the runtime exception that should appear on

o1.o2 = null;
o1.o2.foo = "bar";

is swallowed by the binding code in the Flex framework. You will not see the usually expected runtime exception displayed via the Flash Debug Player. Instead, the following code like the trace( "show foo " + o1.o2.foo ); will just not execute.

Note, that this will only happen with certain exceptions. It will only happen on the following exceptions:

  • Error #1006: Call attempted on an object that is not a function.
  • Error #1009: null has no properties.
  • Error #1010: undefined has no properties.
  • Error #1055: - has no properties.
  • Error #1069: Property - not found on - and there is no default value

For more information on these errors take a look at Run-Time Errors of Adobe Livedocs.

Note also, that this will only happen when your application code in the destination executes in the same ActionScript block. This means if your exception throwing code executes in a different frame (as would usually be the case on a custom effect) you will see a runtime exception as expected.

However, if your application code does throw one of the swallowed exceptions in the same ActionScript block, there are ways so you can see this immediately.

You could use a special debug class in the Flex framework to help you see the error message. Use
mx.binding.BindingManager.debugBinding( <your destination as a String&gt );

But in a production environment I’d recommend you use another more bullet-prove way of solving this problem. You can use the extended version of Paul’s Observe tag.

<ac:Observe
	source="{ stockTransaction.stockPurchase.isComplete }"
	handler="{ createChargedMessage }"/&gt

Using Observe you can invoke a method instead of the setter.

private function createChargedMessage( value : Boolean ) : void
{
	if( value ) Alert.show( "Thanks! Your bank account has been charged" );
}

Try putting the code from above that will throw a runtime exception into the createChargedMessage method. Observe will make sure that a runtime exception is being thrown as expected.
Internally, Observe wraps another global Error handler around your destination, saves the exception thrown and throws it in the next frame.

Furthermore this approach offers an additional feature for your convenience. If you want to listen to only a specific value of the source, you can use ObserveValue for this. In our use case of the iteration 6 Cairngorm Dashboard we just want to know when the isComplete property of our StockPurchase object is true.

<ac:ObserveValue
	id="observe"
	source="{ stockTransaction.stockPurchase.isComplete }"
	handler="{ createChargedMessage }"
	value="{ true }"/&gt
private function createChargedMessage() : void
{
	Alert.show( "Thanks! Your bank account has been charged" );
}

I’ve mentioned above that this also applies to function bindings. In StockMarketPod.mxml of the iteration 6 Cairngorm Dashboard sample application, I’ve used the provided Observe.execute method in order to ensure a secure use of our function binding, which tirggers a custom formatter.

<mx:Label text="{ observe.execute( statusFormatter.format, stockTransaction.status ) }"/>

You can download the Observe and ObserveValue utility classes from here.

Hope this helps!

Posted by auhlmann at September 28, 2006 11:58 AM

Where have ye gone, Observe tag?

June 26th, 2008

The old Macromedia weblogs (at least Alex Uhlman’s blog) seem to be down for the count. However, you can still access the Observe, Observer, ObserveValue tags.

You can download the Observe and ObserveValue utility classes from here.

src: http://weblogs.macromedia.com/auhlmann/archives/2006/09/using_binding_s.cfm#more

If you don’t know what they are, but are looking at using data binding to any measure, with MXML, they’re well worth your time to check out. ;)

Original author’s post is still up

NOTE:
I have posted Alex’s original article, myself - as i believe he has too much useful information here, for it to languish in the brokenNet:
Using Binding Securely

Using FlexBuilder 3 @ mnswf.camp: files

April 7th, 2008

Here’s the files from my presentation on FB3, today.

Sorry that i wasn’t able to present all of my very well-researched quiz questions (thx Danny). ;)

using-fb3_mnswf-camp.zip

updateDisplayList(): Beware!

January 19th, 2008

If you are engaged in or prepared to start developing / customizing components within the Flex framework, consider yourself duly warned. One problem that I’ve found to be pervasive is the simple mistake of explicitly moving / resizing elements within the updateDisplayList() method of the UIComponent class. If the following code is executed within updateDisplayList(), you will trigger an endless loop, as setting these properties on instances of UIComponent invalidates their own display lists, which bubbles up to their parents (’this’) and invalidates that display list as well, which triggers the update chain endlessly:

Wrong:


renderer.x = item.x - layout.xPosition;
renderer.y = item.y;
renderer.width = item.width;
renderer.height = item.height;

Correct:


renderer.move( item.x - layout.xPosition, item.y );
renderer.setActualSize( item.width, item.height );

It is a known problem, but very easy to fall into. So easy, that even Adobe developers have fallen into this pitfall! The problem is exacerbated by the fact that methods called from within updateDisplayList() must also adhere to this practice, which is the case you can see in my post on the Adobe Scheduling Framework’s BackgroundLayout class, where render() contained the offending code, and was being called from within updateDisplayList().

Good luck out there.

Designing workflows within Cairngorm

January 16th, 2008

One problem I’ve been grappling with, and believe many others have and will continue to is the question of managing the flow of control within an application, where complexity expands beyond simple discrete executions. That is, when any stage of the flow may need to wait for asynchronous user/server response, and where each stage may result in numerous outcomes (non-deterministic).

Take for example my own problem where the user is basically in a document management system performing some CRUD ops, but control is decentralized. I’m using Cairngorm in this instance - however, I would assume that the same problem will exist in any decoupled MVC environment. Cairngorm gives you discrete commands, but no real feedback loop. They do provide a SequenceCommand, but by their own doc it can be used to “establish some simple form of decision-based workflow”. However, I’m looking at doing something a little more complex. Lets say I’m editing my doc in my view, but the app is signalled to shut down. In my case, my app is a module within a dashboard, so I need to perform cleanup in order to signal the portal that it can shut me down. Previously, I’d tracked a bunch of state properties in my model, and ended up with a couple of bloated, confusing commands, as well. I knew there had to be a more elegant solution.

I considered some kind of stack-based operation queue, where execution could be monitored, when I ran across Joe Berkovitz’s ReviewTube app. He uses an Operation much like a Cairngorm command, and also has the CompoundOperation which runs through the stack as I imagined it. Basically, these operations become atomic operations at the Command level, where the Command merely becomes the hook for user interaction. I look at them as Sub-Commands. I took his simple code and plugged it into a small doc editor that can be viewed here. It’s a work in progress, and I’m really interested in community feedback to improve this, as it is an over-arching design problem in recent projects. I really want to know if I’m going down the right path, or if there are better ways of doing these kinds of things.

AsynchWorkflowExample:
Example
Source

The heart of the matter is the CloseAppCommand, where you can see the following within the execute() method:


var c:CompoundOperation = new CompoundOperation();

//these are the branches in my workflow
c.addOperation( new CaptureModelChangesOperation() );
c.addOperation( new PerformAppCloseOperation );			

c.addEventListener(ErrorEvent.ERROR, handleFault);
c.execute();

What the CompoundOperation gives me is a list of distinct tasks that must be executed, with feedback at each step. They either pass or fail, and I get to deal with the results. For now, it’s fairly simple and is working, which is already a vast improvement from my previous design!

SchedulingFramework - BackgroundLayout additions

December 13th, 2007

Author’s note:
This post is intended to share updates with the proprietors of http://code.google.com/p/flexlib/. However, it is supplied here to share in case these updates are either delayed or never included in the library!
- Complete source is available at bottom of page.

I found I had troubles with the default behavior of the ScheduleViewer’s background layout. Items appeared to be layed out in a columnar fashion, which would not necessarily align with regular schedule items in the viewer. This can be seen in the supplied examples by zooming in and out. -> Background items will flicker, appear, and disappear, depending on the zoom level! eg: ScheduleViewer6_Sample

So, I’ve added a new class - AbsoluteBackgroundLayout which does lay items out based on absolute times - which will match start/end dates of the schedule items.

However, using this class is a three step process:

First off:
I discovered a bug in flexlib.scheduling.scheduleClasses.viewers.BackgroundViewer where using my custom BackgroundLayout seemed to cause performance issues and could lock up flex controls:

BackgroundViewer.render() becomes:

/**
 * Modified - 12/12/2007 - Scott Langeberg
 *  - Fixed performance bug where setting x,y, width, height caused
 *    updateDisplayList() to loop endlessly
 *  - Refactor to simplify/optimize looping code.
 */
private function render( layout : BackgroundLayout ) : void
{
	if( layout == null ) return;

	var oldRenderers : Array = visibleRenderers;
	visibleRenderers = new Array();

	var item : BackgroundLayoutItem;
	for each( item in layout.items )
	{
		var renderer : BackgroundLayoutItemRenderer = oldRenderers.pop();
		if ( renderer == null ) {
			renderer = getRenderer();
			addChild( renderer );
		}
		renderer.move( item.x - layout.xPosition, item.y );
		renderer.setActualSize( item.width, item.height );
		renderer.setStyle( "backgroundColor", item.backgroundColor );
		renderer.toolTip = item.toolTip;

		visibleRenderers.push( renderer );
	}
	removeUnusedRenderers( oldRenderers );
}

Secondly:
The calculateItems() method of flexlib.scheduling.scheduleClasses.layout.BackgroundLayout must become protected, to allow override:

protected function calculateItems() : void
{
...
}

Lastly:
The new class (usage within comments):

/*
Copyright (c) 2007 FlexLib Contributors.  See:
    http://code.google.com/p/flexlib/wiki/ProjectContributors

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
package flexlib.scheduling.scheduleClasses.layout
{
	import flexlib.scheduling.scheduleClasses.BackgroundItem;
	import flexlib.scheduling.scheduleClasses.layout.*;
	import flexlib.scheduling.timelineClasses.ITimeDescriptor;
	import flexlib.scheduling.util.DateUtil;

	import mx.collections.*;
	/**
	 * AbsoluteBackgroundLayout class causes background items to be layed
	 * out in similar fashion to ScheduleView items - in that items begin and end
	 * on the specified dates. The regular BackgroundLayout class appears to align start/end dates
	 * for items on columns that are calculated off of the timeranges supplied to the ScheduleViewer.
	 * - The original design may be related to the apparent bug caused by overlapping items, and the
	 *   columnar layout may be a workaround for that(?).
	 *
	 * @example
	 * //From: ScheduleViewer6_Sample.mxml
	 * <flexlib:ScheduleViewer id="scheduleViewer"
         * 		width="600" height="400"
         * 	    backgroundLayout="flexlib.scheduling.scheduleClasses.layout.AbsoluteBackgroundLayout"
         * 		dataProvider="{ dataProvider }"
         * 		startDate="{ startDate }" endDate="{ endDate }" />
	 *
	 * @author	Scott Langeberg
	 * 			slangeberg[at]gmail[dot]com
	 * @date	12/12/2007
	 */
	public class AbsoluteBackgroundLayout extends BackgroundLayout
	{
		public function AbsoluteBackgroundLayout()
		{
			super();
		}

		override protected function calculateItems():void
		{
			if ( !backgroundItems ) {
				return;
			}

			var result : ArrayCollection = new ArrayCollection();

			var totalMilliseconds : Number = endDate.getTime() - startDate.getTime();
			var zoom : Number = totalMilliseconds / contentWidth;

			var xStart : Number = xPosition;
			var xEnd : Number = xPosition + viewportWidth; 

			var colorItem : BackgroundItem;
			for each( colorItem in backgroundItems )
			{
				var w:Number = Math.abs(
					colorItem.endDate.getTime() - colorItem.startDate.getTime() );  

				var item : BackgroundLayoutItem = new BackgroundLayoutItem();
				item.width = ( w / zoom );
				item.height = viewportHeight;

				//@NOTE: Overlapping NOT appear cool (as in breakage..)
				item.x = colorItem.startDate.getTime() / zoom;
				item.backgroundColor = colorItem.color;
				item.toolTip = colorItem.description;				

				if( item.x + item.width >= xStart && item.x < xEnd )
				{
					result.addItem( item );
				}
			}	

			_items = result;
		}
	}
}

Complete source files:
AbsoluteBackgroundLayout.zip

Advanced AS3 with Design Patterns (book review)

May 18th, 2007

This book has three fairly different sections, so I will address them in order. The first part concerns ‘Successful Projects’ and I found it to be full of good advice regarding project management, design, and coding best practices. Another great book in this area would be Code Complete. Unfortunately, this section is fairly short and sweet, at around 30 pages. However, this is not the intended focus of the book, either.

The second section concerns ‘Patterns’ and at near 140 pages is the largest of the three. I would not suggest this book to someone who is learning patterns for the first time. For that, I would suggest something like Head First Design Patterns, and I’ve heard that even Patterns for Dummies is good. What I found useful in HFDP is the use of ample illustrations and simple examples, neither of which you will find in ample supply in the AS3 book. What AAWDP does well is show you how to implement patterns in the context of AS3. Some of these implementations can get complicated and at times difficult to track what the full intentions/implications of the pattern is having in the application. I really prefer to see pattern example implementations in a more stripped down format, for easy digestion. In reality, patterns are language agnostic, so you should be able to implement them no matter what the language. However, as the title of this book clearly states, these patterns are for AS3, so if you’re having trouble figuring out how to implement the included patterns, then this text is for you.

Finally, part III covers ‘Advanced AS Topics’ and this is another winner in my book. It follows a kind of cookbook format, with distinct problems and solutions, always following some decent best practices. The section on E4X (XML) is great, because I have a fairly good handle on the topic, and was still able to learn from it.

In my estimation, this book does best when showing you the ‘Advanced’ features and not quite as strong in the ‘Patterns’, but is still worth picking up. I have a feeling I’ll be learning something new, every time I open this densely packed read.

Silverlight brings the magic

May 9th, 2007

I dig how the Silverlight promo video features a guy using two hands to interact with an interface, just like Apple’s new tech they bought…as well as a guy buying his skateboard with a very iPhone-like device!

Apparently Silverlight will support 3D holographic interfaces, floating in space. I’m definitely switching. The future that has been promised by Hollywood movies for years is finally here!

> SilverLight

Not to be outdone, Java has also introduced their own competitor to Flex. Which apparently will make you feel like your at some kind of killer concert.

> JavaFX

Non-breaking DataGrid Headers

May 2nd, 2007

While trying to tweak the display of DataGrids, I had the requirement to create headers that do not break words in the middle. After fiddling with custom renderers, which is not the most enjoyable expedition to take, I came up with a far more lo-tech approach. I realized that the DataGrid handles word-wrapping quite handily, so that I should only need to restrict the minimum width of the column to that of the longest word in the column.

NOTE: This is a work in progress. Feel free to post any improvements that you see. Known improvements would include using text metrics to determine size of characters and to account for padding and the arrow that appears in the header, when sorting.

Requested features:
- Refit column widths to longest cell in column (one problem with this is when you end up with one really wide column on the right..)

//Make sure col stays as wide
//as longest word in header
var col:DataGridColumn = new DataGridColumn();

//Apply col attributes here..
//...

var words:Array = col.headerText.split( " " );
var len:uint = 0;
for ( var i:uint = 0; i<words.length; i++ ) {
   var word:String = words[i];
   len = Math.max( len, word.length );
}			 	

/*
* @TODO: Figure out how to pull actual padding
*   ( AND actual character widths, for that matter)
*   without throwing errors!
*/
var newWd:Number = len * 6;

var pad:Number = 10;

//arrow appears, for sorting
//NOTE: Guessing!
var arrowWd:Number = 10;

col.minWidth = newWd + pad + arrowWd;

//Add col to your columns array
//...

This does achieve my goal for the most part (barring obvious improvements), but I can see this solution being a problem, when you’ve got a lot of columns vying for space, but all setting their minWidth’s to something that adds up to more than the width of the DataGrid!