Thursday, July 10, 2008

PureMVC Pipes - using the filter

The filter is useful for filtering the messages going through the pipes. An analogy you can use is a water filter.


wall ======== [water filter] ========= fridge/sink
pipe1 pipe2



in code form this would look like this:


// create output pipes 1
var pipe1:IPipeFitting = new Pipe();
var pipe2:IPipeFitting = new Pipe();

// create filter
var filter:Filter = new Filter( 'TestFilter' );

// connect input fitting
var connectedInput:Boolean = pipe1.connect( filter );

// connect output fitting
var connectedOutput:Boolean = filter.connect( pipe2 );




the way something gets filtered is this..

1] the message going through the filter must have a variable in the message header,
lets call it particleSize:int.

example:


var h20Message:IPipeMessage = new Message( Message.NORMAL, { particleSize:1, name:'h20'} );
var mineralMessage:IPipeMessage = new Message( Message.NORMAL, { particleSize:10, name:'mineral'} );


2] the filter also needs a paramater to compare wether to let the message through or not, lets call it maxParticleSize.

3] then the filter needs a filter function which checks if the maxParticleSize >= particleSize.


How to setup the filter

to make it do something we have to create the filter and pass in parameters to the constructor.


/**
* Constructor.
*


* Optionally connect the output and set the parameters.


*/
public function Filter( name:String, output:IPipeFitting=null, filter:Function=null, params:Object=null )
{
super( output );
this.name = name;
if ( filter != null ) setFilter( filter );
if ( params != null ) setParams( params );
}


One way to create the filter is to pass in all name, output, filter and params to the functions parameters:


var teeMerge:TeeMerge = new TeeMerge();
var filter:Filter = new Filter( 'waterFilter',
new PipeListener(this,function ( message:IPipeMessage ){trace('particle got through');),
function( message:IPipeMessage, params:Object ):void { if (message.getHeader().particleSize >= params.maxParticleSize) throw new Error('particle filtered'); },
{ maxParticleSize:5 }
);
teeMerge.connect(filter);
junction.registerPipe( PipeAwareModule.STDIN, Junction.INPUT, teeMerge );


above, messages enter input the teeMerge, then goes to the filter, if the filter
accepts the message, it sends it to the pipelistener.



If you look at the Filter constructor you can see output, filter and params are optional and can be set/modified after creation of the filter which I will explain how that works below.

setting the output
filter.connect(a IPipeFitting)

setting the log level/filter function
If you look at Filter's source, its write method is where the filter changes it's log level and filter function. When the filter sees a FilterControlMessage.SET_PARAMS it will then try to set the new params.

below I set the maxParticleSize to 10 because i want the mineral to go through:


var maxParticleSize:number = 10;
var setLogLevelMessage:LogFilterMessage = new LogFilterMessage(FilterControlMessage.SET_PARAMS, particleSize);
filter.write(setLogLevelMessage );


of course, you can send the FilterControlMessage through a modules junction to the
filter using junction.sendMessage as well.

No comments: