All entries for Thursday 23 August 2007
August 23, 2007
My Family and Other Primates, Kruger Park 2007 part 2
Follow-up to My Family and Other Primates, Kruger Park 2007 part 1 from Transversality - Robert O'Toole
1. The boy and his bushbuck, at Letaba
2. Monkeys, not such distant relations
3. Swinging through the trees, near Shingwedzi
4. Lions, a critical assessment
5. Drifting on the thermals, from Shingwedzi to Olifants
6. Elephants are big and grumpy, but fun to watch
Not such distant relations
The little monkey boy lolloped towards the two indignant females, his intent obvious to all but himself. A poorly acted hunchbacked stoop hid his otherwise youthful athleticism, perhaps a tactic to put them at their ease. One day in the future he will be the alpha male of the troop, but for now he is just another buffoon.
He scampered, arms swinging loosely, knuckles almost dragging across the ground as if his species had only recently descended from the tree-tops to explore and exploit savannah Africa. A glint of drool dribbled from the corner of his chattering mouth, sharp white teeth on full display, an ape with a gape. Primitive. And then, with his face close to that of the smaller of the girls, he began his flamboyant mating dance.
In her doctoral thesis, the primatologist Dr Jane Goodall described just such behaviours amongst the chimpanzees of the central African rainforests. Here, in the Kruger National Park of South Africa, the little monkeys were dancing to a similar over excited tune. We watched from a distance, awed by this snapshot of our own simian ancestories. So closely related, as DNA proves, and yet so far.
His two feet repeatedly left the ground almost at the same time, bouncing a short distance into the air, right foot slightly ahead of the left with the syncopation of a jazz band. Landing with a dusty thump, he kicked up a fine cloud of sand towards the young ladies, at last forcing them to acknowledge his presence. Arms outstretched like some great bird struggling for flight, he flapped and bounded on the spot, grunting and blowing. They were, in response, deathly unimpressed.
The young male continued. Throughout the performance, his balance precarious. The older of the females tempered her disdain for the precocious ape with fascination, albeit with nothing other than the improbable physics of his art. Sensing failure, the young male only became more frantic in his attempts to make the girls notice. This impetuosity led to his downfall, when his left foot found an unexpected obstacle: his right foot seemed to have its own rhythms and reasonings. He paused for a second down on his posterior, and then sprang to his feet whilst shooting out both arms as if to say: that was all part of the act, i'm so good I even fall over with style. The older female passed him a sideways glance, and then continued with her own more interesting occupation, examining the jaw bone of a long dead elephant.
Making no progress with the girls, the monkey boy temporarily broke away in order to pick a small stick off the ground. The stick was alas imperfect. There followed a few seconds of motionless consideration, the inner machinations of his brain made visible on his face. We were reminded of George W. Bush 'deep' in thought. A metaphorical lightbulb flashed above his head. Quickly he stripped away the surplus twigs and leaves, creating the perfect stick with which to scrape the bare earth at the feet of the females. Eureka, the primate makes a tool.
He is evolving. But not quickly enough it seems. The females escaped with haste, speeding up a gnarly old tree. The older girl quickly climbed to a couple of metres, her small feet delicately wrapping around its painfully rough bark. The smaller of the two found herself a more gentle route of escape, clambering along a fallen log. Too fast and agile for their persuer.
Finally, the young male was visibly disappointed, staring up at the older female he vocalised his confusion. As experienced monkey watchers, we could easily decipher his primitive chattering:
"Where's your shoes?"
The little monkey boy speaks! But the young females do not quite understand. They are of the Southern African sub-species. He is a member of the superficially similar but actually very different Homo Sapiens Warwicensis, originating in central England, but having been released into the Southern African biome by misguided tourists (it has since caused great damage to the environment in and around the Kruger Park, incessantly raiding kitchens for scraps).
In the field, young females of the Southern Africa sub-species of the Homo Sapien ape can be identified by three distinctive traits: greater than expected physical strength, an ability to climb any surface barefoot (as observed above), and girly pink clothes with a light dusting of sand.
From the safety of her perch, high up in the tree, the older female (Jessica, aged 6) turned towards the observing zoologists and spoke:
"He's a bit of a funny bunny."
"Yes," I replied, "but he is only two years old. His name is Lawrence."
"My sister Rebecca is four."
"Lawrence is on holiday, he is from England."
With Jessica taking the lead, the girls finally became interested in Lawrence. He was, after all, only two years old and English. It was then perfectly fine for him to be a bit of a funny bunny. For the following thirty minutes they explored the trees, the elephant jaw bone, and the various items of furniture and decoration around the restaurant at Shingwedzi Camp. The girls outclimbed and outclambered him. When he fell they picked him up. When he got nervous they comforted him and encouraged him on. After half an hour they were all equally dusty, but very happy.
Three little monkeys playing in the dirt of the Kruger National Park, South Africa.
Lawrence entertaining the ladies at Shingwedzi Camp restaurant
Funky monkey
My first small Cairngorm Flex application (with explanation)
Follow-up to WiMIC Browser – my first big Flex application from Transversality - Robert O'Toole
Explanation
Here is a screenshot of the Navigator window for the project:
The Cairngorm source code is included in the "com" folder (although it could be compiled and included as an external library). The "uk.ac.cairngormtemplate" folder contains my application. This has six subfolders, each containing classes responsible for different parts of the MVC architecture: view, control, command, business (actually meaning data and comms services), model, vo (value object). As with all Flex applications, there is a single container mxml file, called Main.mxml (an mxml file is equivalent to a html file, with code, styles and visual components). I'll start my explanation of this app and Cairngorm with this top-level container.
The Main.mxml file contains four key items:
- a Services component - this contains all of the services used for connecting to external data sources etc;
- the AppController - this maps events onto commands, so that when a ui dispatches an event (a request for something to happen), the correct code does the required job;
- the AppModelLocator - this stores and indexes all of the data models used in the application, all of the data is stored in one place!
- a ViewStack listing all of the alternative user interface views that the app can display.
Here's the code for the ViewStack:
<mx:ViewStack width="100%" paddingBottom="10" paddingTop="10" resizeToContent="true" selectedIndex="{model.currentView}">
<view:InitialView />
<view:AlternativeView />
</mx:ViewStack>
There are two views in this application, an initial view and an alternative. Each view is defined in its own mxml file in the "uk.ac.cairngormtemplate.view" folder. Notice how the selectedIndex property of the ViewStack is bound to the .currentView property contained in the modelLocator (initially set at 0, which means that the first view in the stack is displayed). This means that the currently selected view may be changed by changing the model.currentView property (more on that below).
So now let's drill down into the InitialView component. We can then see the details of what is presented to the user, and what happens when the user responds to that interface.
InitialView is itself an mxml component based upon the standard VBox component. It contains some script and some UI components. Firstly, the script contains a bindable reference to the AppModelLocator singleton. This means that we can bind UI components to data in the AppModelLocator. There is in fact a text component that is bound to a value object (a class that wraps a set of value properties):
<mx:Text text="{model.messageVO.message}" />
Initially this displays the message "Hello everyone".
Below this text component there is a button "translate". Clicking this button calls an actionscript method in the script on the page. The method is called translate(). It could at that point do some validation, or request further input. However, in this case all that we want it to do is fire of a request for the text "Hello everyone" to be translated.
The least impressive Flex app ever
This is where Cairngorm starts:
private function translate():void
{
var cgEvent : DataChangeEvent = new DataChangeEvent("Dumelang");
CairngormEventDispatcher.getInstance().dispatchEvent( cgEvent );
}
The method creates an instance of the DataChangeEvent, passing it the new message "Dumelang". The DataChangeEvent is defined in the "uk.ac.cairngormtemplate.control" folder. It is a cairngorm event extended to carry our message. We can create events that can carry whatever data we need to be passed to a command. (For example, a user types their username and password into a login box, this is then wrapped in a LoginEvent, and the event dispatched. A LoginCommand receieves the event and attempts a login using a LoginDelegate and login service. If succesful, the command changes the current view to one appropriate to a signed in user).
The next step is to dispatch that event and its message to the Cairngorm controller. This should then get passed on to the required "command" object (the command object contains the code for executing the requested command). But how does the controller know which command object to use? Events are mapped on to commands in the control.AppController class:
public class AppController extends FrontController
{
public static const DATACHANGE_EVENT : String = "DATACHANGE_EVENT";
public function AppController()
{
addCommand( AppController.DATACHANGE_EVENT, DataChangeCommand );
}
}
Our request (to translate "Hello everyone") is then passed to a DataChangeCommand object. This is where we do the work that results in the translation. In this simple example, the .messageVO.message of the modelLocator is simply changed to read "Dumelang". However, we could instead refer to an English-Steswana dictionary to retrieve the translation. This might even require the use of an external data service. The DataChangeCommand would then delegate the work of sending this external request to a Delegate class in the "business" folder. The delegate, on retrieving the required translation, calls back to the DataChangeCommand to complete the requried command, or alternatively calls a seperate command.
So, with the text control on the current view bound to the .messageVO.message property in the modelLocator, and that property now altered (by DataChangeCommand) to "Dumelang" that is precisely what the end user sees on their screen.
But what if we also need to change the current view, for example to the AlternativeView control in the ViewStack? Easy. The command simply alters the .currentView property of the modelLocator. As the selectedIndex property of the ViewStack is bound to .currentView, it immediately changes.
In this example, at the end of DataChangeCommand, a second command is requested using a class that I have called ViewChangeEvent.
var cgEvent2 : ViewChangeEvent = new ViewChangeEvent();
CairngormEventDispatcher.getInstance().dispatchEvent( cgEvent2 );
This class calls ViewChangeCommand, which simply alternates between the InitialView and the DefaultView.
Look - it speaks Setswana! and now the view has changed to one with a white background! Hoorah!
Conclusion
This may be a simple example, but I can already see how using the Cairngorm framework will simplify the task of building very complex applications, resulting in better, more rational and sustainable code.