Introducing Sodality

by Tom Byrne 5. May 2009 05:38

Sodality is a runtime AOP (Aspect Oriented Programming) library for ActionScript 3. Simple implementations of Sodality use Metadata to call functions at specific times. Because of this, simple usage is only possible in IDEs that allow custom Metadata (e.g. Flex, FDT, FlashDevelop, etc), although it can be used in a more advanced manner in Flash (and others which don’t allow custom Metadata).

Simply put, Sodality is like an event system, allowing functions to get called in any part of your application when another piece of code dispatches an Advice object.

  1. Basic Example
  2. Basic Concepts
  3. Simple Usage
  4. A Real Example
  5. Further Flexibility
  6. Download Source

1. Basic Example

If somewhere within your app an Advisor class (more on that soon) dispatched a MouseClickAdvice object (for example), like this:

	dispatchEvent(new MouseClickAdvice(this, mouseX, mouseY));

Any other Advisor could catch the MouseClickAdvice like this (the bracketed metadata is what does the magic):

	[Trigger(timing="before")]
public function onMouseClickAdvice(cause:IMouseClickAdvice):void{
trace("Something was clicked at: "+cause.mouseX,cause.mouseY);
}

Or, it could catch the MouseClickAdvice asynchronously (allowing it to take some time before any other Advisors catch the advice) like this:

	private var advice:AsyncMethodAdvice;

[Trigger(timing="before")]
public function onMouseClickAdvice(cause:IMouseClickAdvice,
advice:AsyncMethodAdvice):void{
/* The advice has been caught here, I'm going
to wait 1 second before allowing it to continue.*/
this.advice = advice;
var timer:Timer = new Timer(1000,1);
timer.addEventListener(TimerEvent.TIMER, onTimer);
}
public function onTimer(event:TimerEvent):void{
trace("I'll now allow the advice to continue");
advice.adviceContinue();
}

2. Basic Concepts

The President

Every Sodality Application has (at least) one President, the President monitors and arranges all Sodality processes. Whilst the president doesn’t get used directly by your code to give Sodality the scope of it’s operations. The President must have a reference to some top level DisplayObject, this allows it to detect Advisors being added or removed from the app, usually this is set to the root of your app.

The Advisors

Any class can become an Advisor by implementing the IAdvisor interface, this allows it to specify Metadata above it’s functions telling Sodality when to call the function. In most apps, IAdvisor is only implemented by DisplayObjects which get added to the stage, non-visual advisors normally extend the DynamicAdvisor class, which allows them to be easily added to the President.

The Advice

Each Advice object represents an operation which will be executed, Advice objects are dispatched like events from any IAdvisor. Normally, each type of request will have an interface associated with it, the Advisors then will listen for the interface (rather than the class) which allows any Advice class to implement as many of these request types as required.

3. Simple Usage

Normally, Sodality is used for broad-scale communication between parts of an application. There are reusable DynamicAdvisors which specify several Advice interfaces allowing your app to instruct the DynamicAdvisor how to behave.

A good example of this would be the SoundAdvisor, which is used to play sounds, adjusting each sound’s volume appropriately and making sure the wrong sounds do not overlap. The SoundAdvisor specifies many Advice interfaces (e.g. IAddSoundAdvice, IRemoveSoundAdvice, IChangeVolumeAdvice, etc.), each of these correspond to a method within the SoundAdvisor. When an Advice object that implements one of these interfaces gets dispatched from another Advisor the SoundAdvisor’s corresponding method will be called and it will have an opportunity to make the required changes (e.g. begin playing a sound, adjust the volume etc.). These Advice interfaces can specify any functions or getters that the SoundAdvisor requires to complete the request, for example, the IChangeVolumeAdvice could look something like this:

package examplePackage
{
import org.farmcode.sodality.advice.IAdvice;

public interface IChangeVolumeAdvice extends IAdvice
{
function get volume(): Number;
function get muted(): Boolean;
}
}

This means that whenever an Advice object implements the IChangeVolumeAdvice interface, it must specify a volume and whether the SoundAdvisor should be muted, which is all the information that the SoundAdvisor needs to complete the request. The reason that interfaces are used instead of classes is so that each Advice object can implement many different interfaces, which will each execute different requests across different Advisors.

4. A Real Example

Stay tuned, we’ll be posting a real example with source code very soon.

5. Further Flexibility

Sodality has been built to be flexible, there are still unexplored pieces of flexibility within it’s architecture, we’d love to see how other people use Sodality and where it goes from here. These are some examples of under-explored areas in Sodality:

IAdviceTrigger

IAdviceTriggers are the object which tie pieces of advice together, they’re a powerful tool which is usually hidden from view, they can dramatically change the functionality of Sodality.

President Monitors

Because of the Asynchronous way that Sodality runs, classes which affect/monitor the running of Sodality can easily be plugged in. Here are some examples of tools we’ve built on to this:

  • A (faux) threading system, which allows different advice streams to take up different amounts of processing time.
  • A step-through debugger
  • A hot-key which traces out any currently pending advice.

Whilst we haven’t open-sourced these, they are good examples of the types of options that are available.

6. Download Source

 

Categories: Flash | Sodality

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading