Flex: Asset lookup dictionary

Here is the latest events panel from my gTraffic rewrite in Flex here ever after to be called (until I change my mind) ‘flexTraffic’

flexTraffic event panel

One of the important parts of the original application was a lookup of a traffic event ‘severity’ and ‘category’ to fetch the appropriate icon for the map and the events panel (DataGrid now). This was offloaded into the Python script which generated the an atttribute with a path to the icon in the XML. I could have recreated this in the Flex code but I didn’t want to rewrite the Python script to alter the path and I had the impression that embeddeding the icons into the Flex app was ‘the right thing to do’.

I reimplemented this lookup in ActionScript as a Dictionary of Dictionaries keyed on the same elements. This was pure graft as I was using the images contained within a Assets class which had the icons as embedded elements i.e. I had to explicity state the strings and the appropriate Class elements (images) to return from the lookup. As example for the roadworks would be:


assetDict[TXT_ROADWORKS] = new Dictionary();
assetDict[TXT_ROADWORKS]
[TXT_SEVERITY_VERYSEVERE] = model.assets.roadworkPanelSevere;
assetDict[TXT_ROADWORKS]
[TXT_SEVERITY_SEVERE] = model.assets.roadworkPanelSevere;
assetDict[TXT_ROADWORKS]
[TXT_SEVERITY_MEDIUM] = model.assets.roadworkPanelMedium;
assetDict[TXT_ROADWORKS]
[TXT_SEVERITY_SLIGHT] = model.assets.roadworkPanelSlight;
assetDict[TXT_ROADWORKS]
[TXT_SEVERITY_VERYSLIGHT] = model.assets.roadworkPanelSlight;
assetDict[TXT_ROADWORKS]
[TXT_SEVERITY_UNKNOWN] = model.assets.roadworkPanelSlight;
assetDict[TXT_ROADWORKS]
[TXT_SEVERITY_UNSPECIFIED] = model.assets.roadworkPanelSlight;

Please note, I have compacted the code to fit into this blog. See the code here..

The PanelSeverityRenderer now has:


public function getSeverityIcon(category:String, severity:String):Class
{
var result : Class = TrafficAssetDictionary.
                           getInstance().lookup(category, severity);

return result;	
}

So the severity renderer now calls a singleton which contains the lookup table. The original code was this:


public function lookup(category:String, severity:String):Class
{
var item:Class = null;
            
item= assetDict[category][severity];

if (item==null) 
   item = assetDict[TXT_UNKNOWN][TXT_SEVERITY_SLIGHT];
            
return item;
}

So far so good but I noticed that some rows didn’t have an icon. A little debugging later and I discovered that my assumption that the Dictionary lookup would return null if it couldn’t find a match was incorrect (some categories are not included in the lookup, too much work). What was happening instead was that a silent exception was being thrown. This didn’t show up even in debug mode which was a little disconcerting and meant I was scratching my head quite a lot.

The solution is that you have to put a try..catch around a dictionary lookup to see if it fails:


public function lookup(category:String, severity:String):Class
{
var item:Class = null;
            
try
{
item= assetDict[category][severity];
}
catch (e:Error)
{
item = assetDict[TXT_UNKNOWN][TXT_SEVERITY_SLIGHT];
}
            
return item;
}

It would be nice I think if Flex would adopt the java Hashmap functionality and return a null for a failed lookup.

Comments

Leave a Reply