Kiichigo

Rich Internet and Agent Oriented Consulting with Raspberry Flavor

Archive for the ‘actionscript’ tag

Route Framework: Routes

without comments

Summary

Before we start, I want to point out, that this article covers low-level API of Route Framework. In most case you don’t want to worry about low-level, unless you building your own framework on top or with Route Framework

Center of Route Framework are IRoute and it’s implementor Route hence the name of the framework. Route sort of inspired by Agent Oriented1 approach minus concurrency and proactivity and EventHandlers from Mate Framework2. Generally it consists of three types of instances: ISensor, IPattern and IAction.
Simply put:

  • Sensor get’s messages from Environment, which uses some way to send and receive messages, whether it’s flash.events.Event or some custom solution.
  • After sensor received message, it parses it if needed and passes it’s to IRoute.perceive( percept:Object ); method. In future we’ll call “sensed” message – percept.
  • IRoute will match percept against IPattern
  • If successful Route will then execute it’s IAction

.
This allows IRoute to be very agile Inversion of Control3 container. Each part of a framwork is simple enough system that can be easily modified.

Percept

Plainly speaking percept can be anything: Object, String, Event or any kind of instance. Whatever Sensor retrieves from Application and passes to Route considered to be Percept. Percept will then be matched against Patterns and passed along to Actions assigned to current Route.

Sensor

In lamen terms Sensor is an Event Listener or an instance of Observer. It simply receives messages from Application/Environment. Of course Sensors can be internal too. For example there could be a Sensor that listens to internal messages of other Routes, but that’s more rare case.

Pattern

Plainly put, Patterns used by Route to see if Actions will be executed. For example Handle Route:

route( Handle, { event: SampleEvent.BIND_PLEASE, generator: SampleEvent } ).
<route:Handle event="{SampleEvent.BIND_PLEASE}" generator="{SampleEvent}"/>

Uses two patterns, to filter by Event.type and actual Class of Event.

Actions

Actions are variation on Command Design Pattern5. Predefined actions in package eu.kiichigo.route.actions cover basic Application manipulation such as: Apply/Bind/Copy data, run closure or method on class, invoke RPC operation and such. You can extend Action, AsyncAction or Actions classes in order to create custom functionality.

There is two major things you can do with actions: assign predicates and group actions

Conclusion

This covers basic logic of Route, once again, this is low-level API which most programmers should not concern themselves with.

Footnotes

[1] PDF: Shoham, “Agent-oriented Programming”.
[2] Mate Framework.
[3] Martin Fowler about IoC.
[4] Command Pattern at Wikipedia.

Written by nirth

February 15th, 2011 at 1:58 pm

Route Framework: Guards and Execution Control

without comments

Most instances of IAction also implement IGuarded interface, that allows programmer to control when certain actions will be executed. It acts a lot like guards from declarative languages, such as Prolog, Erlang or Scala. Essentially speaking: if IGuard.when evaluates into true IAction will be executed successfully, otherwise it won’t.

Predicate for guard ( value of IGuard.when ) can be in a form of: Boolean, function ():Boolean or function ( percept:Object ):Boolean. Here is small example with fluent dsl:

var router:IRouter = new Router().
	route( Handle, { event: LoginEvent.LOGIN } ).
		run( Run, { closure: Alert.show, arguments: ["Logging in "] } ).
			when( check ).
end;

protected function check( percept:LoginEvent ):Boolean
{
	if( percept.username == null || percept.username.length == 0 ||
	    percept.password == null || percept.password.length == 0 )
		return false;
	return true;
}

Action Run will be executed only if incoming LoginEvent has defined username and password. Of course, you will prefer sophisticated validation than simple length check.

Following example shows how to use multiple IGuarded.when predicates with some Functional Programming mojo:

var router:IRouter = new Router().
	route( Handle, { event: LoginEvent.LOGIN } ).
		run( Run, { closure: Alert.show, arguments: ["Logging in "] } ).
			when( check( "username" ) ).
			when( check( "password" ) ).
end;

/**
 * Checks if <code>String</code> that's evaluated via <code>percept[property]</code> is not empty and is not <code>null</code>.
 *
 * @param	property	<code>String</code> name of property on <code>percept</code> argument.
 * @param	percept		<code>percept</code> received by <code>IRoute</code> for testing.
 *
 * @returns	<code>Boolean</code>. <code>true</code> if string is not <code>null</code> and contains at least 1 symbol, <code>false</code>otherwise</code>.
 */
protected function checkString( property:String, percept:LoginEvent ):Boolean
{
	var string:String = percept[property];
	if( string == null || string.length == 0 )
		return false;
	return true;
}

/**
 * Higher order function. Simplistic Curry function.
 */
protected function check( property:String ):Function
{
	return function( percept:LoginEvent ):Boolean
	{
		return checkString( property, percept );
	}
}

I’ve used Higher Order Function, to construct actual predicates. If you have some experience working with Functional Programming, you will find this methods more elegant and logical.

MXML syntax also allows us to use Data Bindings in this example:

<route:Router id="router">
	<route:Handle event="{ LoginEvent.LOGIN }">
		<route:Run closure="{ Alert.show }" arguments="{ ['Logging in'] }"
			   when="{ router.percept.username != null && router.percept.username.length > 0 &&
					   router.percept.password != null && router.percept.password.length > 0 }" />
	</route:Handle>
</route:Router>

No additional functions are requited.

This is rather simple, yet very powerful mechanism of controlling execution cycle of application, without need to create special actions that will check data before execution that can be achieved by simple injection of a guard.

Example and Sources

Futher Reading

About Guards on Wikipedia.

Written by nirth

February 13th, 2011 at 6:05 pm

Route Framework: Sensors and Routing

without comments

In Model View Controller or Delegate Model architectures special place is reserved to messaging system. When it comes to ActionScript, we usually utilise one of three solutions:
flash.events.Event/flash.events.IEventDispatcher.
custom Observer implementation.
AS3 Signals by Robert Penner.

Usually Application Framework comes tightly coupled with some or another messaging library. It might work in many cases, but sometimes it might be a serious bottleneck*. Route Framework can switch messaging systems easily by subclassing just 2 classes: Sensor, that will receive messages, and Route to wrap sensor and pattern in it.

Let’s consider following example with custom Observer Implementation:
IMessage.as

package observer
{
	public interface IMessage
	{
		/**
		 * IMessage name, can be used for additional filtering.
		 */
		function get name():String;
		/**
		 * @private
		 */
		function set name( value:String ):void;

		/**
		 * Any data that can be sent with IMessage
		 */
		function get data():Object;
		/**
		 * @private
		 */
		function set data( value:Object ):void;
	}
}

IObserver.as

package observer
{
	public interface IObserver
	{
		/**
		 * Invoked automatically by instance of IObservable. Should contain any update logic.
		 *
		 * @param message		IMessage sent by IObservable
		 */
		function update( message:IMessage ):void;
	}
}

IObservable.as

package observer
{
	public interface IObservable
	{
		/**
		 * Adds an instance of IObserver to notify queue.
		 *
		 * @param observer		IObserver to be added.
		 */
		function add( observer:IObserver ):void;

		/**
		 * Use this methods, to notify all instances of IObserver added to current IObservable.
		 *
		 * @param message		IMessage to be sent.
		 */
		function notify( message:IMessage ):void;
	}
}

You can check actual implementation of this interfaces in sources, but implementation does not really matter in this case.

In order to teach Route to accept Messages all we need is to subclass Sensor and Route as follows:

package observer
{
	import eu.kiichigo.route.pattern.*;
	import eu.kiichigo.route.pattern.match.type;
	import eu.kiichigo.route.routes.*;

	/**
	 * Version of IRoute to work with custom Observer pattern implementation.
	 * Fluent style:
	 * 
	 * route( Receive, { from: "idOfObserver" } );
	 * 
	 * MXML Syntax:
	 * 
	 * 
	 * 
	 *
	 * @author David "nirth" Sergey
	 *
	 */
	public class Receive extends Route implements IRoute
	{
		public function Receive()
		{
			super();

			// Setup pattern to filter out messages of correct type.
			var p:IPattern = new Pattern;
				p.matcher = type;
				p.store( "type", IMessage );
			// Inject pattern.
			pattern = p;
			// Inject Sensor.
			sensor = new ObserverSensor;
		}

		// Receive.from is simple proxy get-set accesor
		/**
		 * @copy		ObserverSensor#from
		 */
		public function get from():Object
		{
			return ( sensor as ObserverSensor ).from;
		}
		/**
		 * @private
		 */
		public function set from( value:Object ):void
		{
			( sensor as ObserverSensor ).from = value;
		}
	}
}
import eu.kiichigo.route.sensors.Sensor;

import observer.IMessage;
import observer.IObserver;
import observer.Messenger;

class ObserverSensor extends Sensor implements IObserver
{
	/**
	 * @copy		observer.IObserver#update
	 */
	public function update( message:IMessage ):void
	{
		send( message );
	}

	/**
	 * @private
	 */
	protected var _from:Object;

	/**
	 * Indicates an instance of IObservable that this ISensor is listening too.
	 */
	public function get from():Object
	{
		return _from;
	}
	/**
	 * @private
	 */
	public function set from( value:Object ):void
	{
		//ToDo: Handle removal from old Messenger here.
		_from = value;
		Messenger.get( value ).add( this );
	}
}

Now our class has nice readable class name and accessor name, and it’s actually reads as: “Receive from accessorId” as in example:

const router:IRouter = new Router().
	route( Receive, { from: "leftButtons" } ).
		action( Run, { closure: Alert.show, arguments: ["Received message from leftButtons"] } ).
	route( Receive, { from: "rightButtons" } ).
		action( Run, { closure: Alert.show, arguments: ["Received message from rightButtons"] } ).
end;

Alternatively you can use MXML Syntax too:

<route:Router>
	<observer:Receive from="leftButtons">
		<route:Run closure="{ Alert.show }" arguments="{ ['Received message from leftButtons'] }" />
	</observer:Receive>
	<observer:Receive from="rightButtons">
		<route:Run closure="{ Alert.show }" arguments="{ ['Received message from rightButtons'] }" />
	</observer:Receive>
</route:Router>

Example and Sources

* Another framework that handles decoupling of messaging from mvc logic very nicely is Parsley framework.

Written by nirth

February 9th, 2011 at 8:43 pm

Route Framework: Interfacing

without comments

[ToDo: add link to Route Framework introduction]
[ToDo: add link to overview of the Route]

There is 3 basic ways of working with Route Framework: ActionSctipt, ActionScript-Fluent and MXML.
ActionScript: Allows you to work with Route Framework on a low level. It should be used in case you are interested in generating FrontControllers in Runtime from Configuration files or Data Base settings.
Fluent: This is also a way of defining Routers in ActionScript, but much less verbose, and easier to read and define. em>You can read more about fluent programming on Martin Fowler’s Bliki.
MXML: This style allows programmer to define Routers in MXML.

Let’s get some abstract but nevertheless good example: We’ll create two TextAreas original and copy and link their values via Model which we call LabModel. Overral data flow can be represented as:
original.text → labModel.text → copy.text

ActionScript: Low Level

// Create a pattern that will match input to flash.events.Event:
var eventPattern:IPattern = new Pattern;
	eventPattern.matcher = eu.kiichigo.route.pattern.match.type;
	eventPattern.store( "type", flash.events.Event );

// Create Pattern that will match "bindPlease" string.
var bindPleasePattern:IPattern = new Pattern;
	bindPleasePattern.matcher = eu.kiichigo.route.pattern.match.values;
	bindPleasePattern.store( "type", "bindPlease" );

// This action will bind view to model
var view2model:Bind = new Bind;
	view2model.from = original;
	view2model.to = LabManager;
	view2model.text = "text";

// And this will bind model to view.
var model2view:Bind = new Bind;
	model2view.from = LabManager;
	model2view.to = copy;
	model2view.text = "text";

// Create Route that will be catching "bindPlease" events:
var routeBindPlease:IRoute = new Route;
	routeBindPlease.pattern = new Patterns( eventPattern, bindPleasePattern );
	routeBindPlease.add( view2model );
	routeBindPlease.add( model2view );
	routeBindPlease.sensor = Events;

var router:eu.kiichigo.route.kore.IRouter = new eu.kiichigo.route.kore.Router;
	router.add( routeBindPlease );

Here is what happens:

  • We define two patterns:
    • First will match incoming percepts and filter by Class: percept is flash.events.Event
    • Second pattern checks value: percept.type = "bindPlease"
  • We then create two instances of Bind actions and set them up.
  • We create instance of Route and inject Patterns, Actions and Events-Sensor.
  • We add Route to Router.

    Fluent and MXML

    Following two examples show how same logic can be defined in Fluent and MXML DSLs:

    var router:IRouter = new Router().
    	route( Handle, { event: "bindPlease" } ).
    		action( Bind, { from: original, to: LabManager, text: "text" } ).
    		action( Bind, { from: LabManager, to: copy, text: "text" } ).
    end;
    <route:Router>
    	<route:Handle event="{ 'bindPlease' }">
    		<route:Bind from="{ original }" to="{ LabManager }" text="text" />
    		<route:Bind from="{ LabManager }" to="{ copy }" text="text" />
    	</route:Handle>
    </route:Router>

    I want to stress attention on Handle. Handle is one of the pre-defined types of Route that handles percepts of flash.events.Event. There is other Route types available:
    ValueObject: Will perceive and process data from RPC services.
    Inject: Will perceive and process created by Router instances, or added DisplayObjects to DisplayList.
    Programmer can also create own Routes and Sensors to work with other ways of messaging, such as custom implementation of Observer or Delegating Event Model design patterns.

    Example and Sources

  • Written by nirth

    February 9th, 2011 at 1:44 pm

    Functional approach to working with Arrays in ActionScript

    without comments

    Actually I’ll be working with Vector but since I’m passing theoretical knowledge – that won’t be a problem.
    Say we want to play my favorite game: Fizz-Buzz[1], first I’ll create two helper methods that will do most list creation and number checking, to remove details from our way:

    /**
     * Utility factory method, creates simple ranges of numbers.
     * @param from	Initial number.
     * @param to	Target number
     * @return 		Vector. of number in range from and to.
     */
    protected function range(from:int, to:int):Vector.
    {
    	var result:Vector. = new Vector.;
    	var current:int = from;
    
    	while(current != to)
    		if(from < to)
    			result.push(current++);
    		else
    			result.push(current--);
    
    	result.fixed = true;
    	return result;
    }
    /**
     * Simple helper method, emulates "Fizz-Buzz" game, returns "Fizz" if number dividable by 3, "Buzz" if by 5, and "Fizz-Buzz" if by both.
     * @param number	Number to check.
     * @return 			"Fizz" if number is dividable by 3, "Buzz" if by 5, and "Fizz-Buzz" if by both.
     */
    		protected function fizzBuzz(number:int):String
    		{
    			if(number % 3 == 0 && number % 5 == 0)
    				return "Fizz-Buzz";
    			else if(number % 3 == 0)
    				return "Fizz";
    			else if(number % 5 == 0)
    				return "Buzz";
    			else
    				return "";
    		}

    First method as you already guessed simply creates ranges of number, while second checks individual number on it's fizz-buzz-ines. Structural approach would be to create a loop:

    protected function structural():void
    {
    	for each(var number:int in range(1, 101))
    		trace(fizzBuzz(number));
    }

    No surprise here I guess, using for instead of for each could be smarter but I was going for shortness here. But there is a functional approach too:

    protected function test():void
    {
    	range(1, 101).forEach(loop);
    }
    /**
     * Used as a callback in Array.forEach or Vector.forEach methods.
     * @param element	Current element.
     * @param index		Current index.
     * @param vec		Reference to the Vector.
     */
    protected function loog(element:int, index:int, vec:Vector.):void
    {
    	trace("[" + index + "] " + fizzBuzz(element));
    }

    This approach does not look short*, but it gives us some flexibility because we've just reached new level of abstraction and went beyond Object Oriented. Here is better example:

    /**
     * Higher order function that creates a loop closure.
     * @param output	Reference to the desired output method, such as "trace".
     * @return 			Function with selected output method.
     *
     */
    protected function looper(output:Function):Function
    {
    	return function(element:int, index:int, vec:Vector.):void
    	{
    		output("[" + index + "] " + fizzBuzz(element));
    	}
    }

    Method looper is a Higher Order Function (hof) instead of doing anything - it creates and returns another function, we also pass closure/function as argument, this gives us ability to change way we want to output information, we can easily switch between trace, ILogger.log or any custom debug method myDebugger.debug, and we can do it fluently:

    range(1, 101).forEach(looper(trace)); //using trace()
    range(1, 101).forEach(looper(myLogger.log)); //using Flex Logger
    range(1, 101).forEach(looper(console)); //my custom debug method that traces items to Firebug Console

    No ActionScript IDE support functional approach to programming, so I wouldn't recommend heavy use of fp, but there is places where FP (Functional Programming) can be very helpful, such as Game AIs, which might need to easily discard unworking tactics and try new ones, without storing whole classes/modules of tactics and plans in memory. I also found that it's quite usable to use FP in small utility and helper functions, just make sure that your team understands what it is.

    * At least it does not look that short in ActionScript, but you might be surprised by it's elegance in languages like Ruby, Scala, Erlang and Haskell.

    [1] Coding Horror: FizzBuzz

    Written by nirth

    October 28th, 2010 at 5:13 pm

    ActionScript for .NET 3.0

    without comments

    Well, to be honest this is not competely truth, we cannot write in ActionSctipt for .NET 3.0, but we can write in JScript which is subtype of JavaScript 2.0, which is ECMA4… well this is just like ActionScript 3.0 ;) . The only one seriouse difference is classes and their location, but we still have ByteArray, BitmapData\Bitmap and ColorMatrix (which is ColorMatrixFilter in AS) and bunch of other similar classes.

    Now, .NET 3.0 is compatable with version 1 and 2, so that means that we can compile library for .NET 2 and use it in our WPF/E-.NET 3.0 project.

    For this mini tutorial you’ll need .NET 3.0 and Microsoft Expression Interactive Designer.
    Read the rest of this entry »

    Written by nirth

    October 3rd, 2006 at 3:52 am

    Posted in Uncategorized

    Tagged with , ,