Hitman.com live for some months now
A high-profile use of Birdbase has been live since June, and we are happy to share.
From Square-Enix.
A high-profile use of Birdbase has been live since June, and we are happy to share.
From Square-Enix.
Not much to report
Birdbase is stable, we’ve updated the dependencies internally and nothing broke, so that’s all good.
Looking into buying a Flash Builder 4.5 licence so we can provide examples and tutorials for making iOS, Android and Blackberry apps. We tested it with the trial version and all we had to do was ensure that the resources were bundled in. Easy!
A user recently had a compilation issue on FDT; see here for the thread on Github. There was a stray dependency in the as3-navigator library which we took the opportunity to cleanup, as well as updating the AssetLoader to the latest version, 2.3.4.
The fix worked out, and so the latest BirdBase is actually available within the demo site, rather than on the BirdBase repo. We’ll get around to checking the core code and ensuring it really is a proper release before we update the main repo.
This means that the demo site should compile cleanly on Flash Builder, FDT and with Sprouts/Rake. Thanks to Alistair Colling for reporting the issue.
Apologies for the long break – we’ve been finishing off the production site.
Trying to get the filesize and dependencies down as part of the optimization process. So here’s version 0.8.2.
The BirdBase Demo Site has been updated to use the latest – development version – of SWFAddress.
If you see errors like this:
[Fault] exception, information=ArgumentError: Error #1063: Argument count mismatch on com.asual.swfaddress::SWFAddress$/_setValue(). Expected 2, got 1.
at Function/http://adobe.com/AS3/2006/builtin::apply()
at flash.external::ExternalInterface$/_callIn()
at Function/()
Then update your SWFAddress Actionscript and Javascript from either the Demo Site on Github or the Asual repository here.
The BirdBase Demo Site has been updated to use the latest BirdBase lib, 0.8.2, and we will push the changes into the BirdBase repo shortly.
A commenter just asked, ‘Docs say “The TextService supports runtime dynamic reloading of strings, so if these are reloaded, in say, a different language, all your IHaveUpdateableText instances will be reformatted and updated immediately.”
How do I reload strings dynamically?’
Good question. Let’s start by seeing how the strings are loaded in the first place.
The strings are kept – initially – in the configuration.yml file. It’s convenient and straightforward, and the section looks something like this:
strings:
home_title: "Home Section"
media_title: "Media Section"
news_title: "News Section"The configuration is loaded into the ConfigurationService by the D_Services command in org.birdbase.framework.controller.core.
Once the configuration is loaded successfully, we parse the YML into a dictionary and deliver it to various objects:
(ConfigurationService)
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | private function handleComplete( e:Event ) : void { try { var d:Dictionary = YAML.decode( e.target.data ) as Dictionary; setConfiguration( d ) setStrings( d ); setPreferences( d ); setNavigation( d ); eventDispatcher.dispatchEvent( new StateEvent( StateEvent.ACTION, BootManagement.CONFIGURING_SERVICES_COMPLETE ) ); } catch( e:Error ) { fatal( e.message ); eventDispatcher.dispatchEvent( new StateEvent( StateEvent.ACTION, BootManagement.CONFIGURING_SERVICES_FAILED ) ); } } |
Line 104 above calls the setStrings function which basically sends the strings chunk of the parsed YML to the TextService:
78 | textService.strings = d.strings; |
The TextService then updates any updateable components that are registered. And that’s it.
So, the way to update the strings dynamically is to simply set them on the TextService instance. But how do we load a new file in?
The new YML should look exactly like the strings section in the configuration.yml, although the values will be different:
strings:
home_title: "Accueil"
media_title: "Medias"
news_title: "Nouvelles"So we ought to have an URLLoader to load this for us.
[Inject] public var textService:ITextService; var loader:URLLoader = new URLLoader(); loader.addEventListener( Event.COMPLETE, handleComplete ); loader.load( new URLRequest( "<path/to/my/new/strings/file.yml>" ) ); function handleComplete( e:Event ):void { var d:Dictionary = YAML.decode( e.target.data ) as Dictionary; textService.strings = d.strings; }
And the TextService will update all your registered components.
A one-line fix that corrects the behaviour of a site to redirect to its root if you refresh the browser.
https://github.com/vishvish/BirdBase
Deep-linking in BirdBase is provided by integrating the navigator-as3 library, written by Eric-Paul Lecluse.
The navigator gives us a number of useful things:
Firstly, we may wish to map the URL “/news” to the NewsView. Easy. But suppose we want to map “/news/1″ and “/news/2″ to the NewsView as well? In our configuration, we can simply pass in an array: [ "/news", "/news/*" ] which covers all of those URLs.
Secondly, how does the transition management prove useful? Well, simply switching between views is possible, but may not be desirable, or there may be processing required during the switch, say some animation occurs. Well, navigator-as3 has a few interfaces that may be implemented.
com.epologee.navigator.behaviors.IHasStateTransition describes two methods, transitionIn and transitionOut. These are probably best implemented on the Mediator and are called by the Navigator when it wants to show or hide the view. There is one argument to both of these methods, a callback function. Your transition code lives in these methods and then the callback is fired to let the Navigator know that it may carry on.
Example of transitionOut method:
override public function transitionOut( callOnComplete:Function ):void { // put your code here // fade view out // cleanup // fire callback callOnComplete.call(); }
There is further information on the navigator-as3 here. It’s worth noting that Eric-Paul’s RobotLegs integration is in progress right now, and BirdBase DOES NOT use it anyway as per EP’s instructions. As BirdBase allows us to do view mapping directly in the configuration, BirdBase simply instantiates the elements of the navigator directly and maps Views and Mediators directly into the navigator.
Compiling a Main.as class and running a flash application is pretty easy if all you want to do is draw a square on screen and print “Hello, World!” into a TextField. Applications sometimes need to do a whole bunch of things before the user gets control. Examples:
BirdBase handles these things during its Bootstrap process, and the class that runs all this is BootManagement in the org.birdbase.framework.controller.boot package. The Bootstrap runs a series of commands, one after the other, and waits for each one to complete successfully before moving onto the next one. This is run by code known as a Finite State Machine, or FSM. The FSM has its roots in the PureMVC framework, and was ported over to RobotLegs by Joel Hooks.
The command steps are found in the org.birdbase.framework.controller.core package, and labelled alphabetically from A to E, in the order that the Bootstrap runs them.
The BootManagement class configures the FSM, and we will now break down the code to explain how each section works.
public static const FSM:XML = <fsm initial={STARTING}> <!-- THE INITIAL STATE --> <state name={STARTING}> <transition action={STARTED} target={CONFIGURING_PREFERENCES} /> <transition action={START_FAILED} target={FAILING} /> </state> <state name={CONFIGURING_PREFERENCES} changed={CONFIGURE_PREFERENCES}> <transition action={CONFIGURING_PREFERENCES_COMPLETE} target={CONFIGURING_NAVIGATOR} /> <transition action={CONFIGURING_PREFERENCES_FAILED} target={FAILING} /> </state>
SNIP…
<state name={LOADING_ASSETS} changed={LOAD_ASSETS}> <transition action={LOAD_ASSETS_COMPLETE} target={STARTING_APPLICATION} /> <transition action={LOAD_ASSETS_FAILED} target={FAILING} /> </state> <state name={STARTING_APPLICATION} changed={START_APPLICATION}> <transition action={START_APPLICATION_COMPLETE} target={READY} /> <transition action={START_APPLICATION_FAILED} target={FAILING} /> </state> <!-- READY TO ACCEPT BROWSER OR USER NAVIGATION --> <state name={READY} changed={GO} /> <!-- REPORT FAILURE FROM ANY STATE --> <state name={FAILING} changed={FAIL} /> </fsm>;
SNIP…
commandMap.mapEvent( BootManagement.LOAD_ASSETS, E_Assets, StateEvent, true ); commandMap.mapEvent( BootManagement.GO, ApplicationReady, StateEvent, true ); commandMap.mapEvent( BootManagement.FAIL, ApplicationFault, StateEvent, true ); eventDispatcher.dispatchEvent( new StateEvent( StateEvent.ACTION, BootManagement.STARTED ) ); }
state node above describes a command step, and within the step we are most interested in the transition nodes.STARTED on line 30, the target is CONFIGURING_PREFERENCES. Move to the CONFIGURING_PREFERENCES state. You can see on line 120 that we are mapping the “changed” attribute CONFIGURE_PREFERENCES to the command A_Preferences in org.birdbase.framework.controller.core.CONFIGURING_PREFERENCES is complete? Or has failed? The onComplete method in A_Preferences:private function onComplete():void { eventDispatcher.dispatchEvent( new StateEvent( StateEvent.ACTION, BootManagement.CONFIGURING_PREFERENCES_COMPLETE ) ); }
BootManagement.CONFIGURING_PREFERENCES_COMPLETE. And BootManagement moves onto the next step, which is CONFIGURING_NAVIGATOR and not displayed in the snippet above. But eventually, assuming successful completion of each step, we end up at your context:commandMap.mapEvent( BootManagement.START_APPLICATION, StartApplication, StateEvent, true );
StartApplication command. And we call the ApplicationReady command in BirdBase to startup the navigator and hand over control to the user.Get it here: https://github.com/vishvish/BirdBase-Demo-Site.
See the demo in action here: http://demo.birdbase.org/demo-application/v1.0/