Decorators in TIScript, fun of UI programming is back.

January 26, 2009

Filed under: Sciter,Script — Andrew @ 10:21 pm

Latest builds of the Sciter have decorators implemented. My implementation of decorators ideologically derived from the same decorator feature in Python of Guido van Rossum.

Decorators is a meta/macro-programming feature that allows to transform or update function or class defined in source code.

Here is an example: say we are designing some dialog with various input elements and buttons. Usually code behind such dialogs is a collection of simple “if-we’ve-got-some-event-here-then-update-state-over-there” blocks. First part (if-we’ve-got-some-event-here…) of the task is repeating again and again. The desire is to make it as short and clear as possible. With decorators this could be written as:

@when Event.BUTTON_CLICK @on "button#add-new" :
   {"#list").insert( new Element( "option", "new item") );
@when Event.SELECT_SELECTION_CHANGED @on "select#list" :
   {"#delete-current").state.enabled = true;

This makes such sequence of blocks to look more like a table of records: when (event) on (where) (then do this). That is more declarative approach if you wish. This code is better maintainable I think.

@when and @on here are decorators of anonymous function that follow them. ( Sequence :{ ... } declares anonymous function in TIScript ).

Decorator in TIScript is an ordinary function with the name starting ‘@’ and at least one parameter. This first parameter is a reference to function that is being decorated. Decorator-function in its turn can dynamically create another function that will wrap call of original function.

Here is how our @when and @on decorators might look like:

// decorator '@when' - filters event by type 
function @when(func, evtType)
      return self.onControlEvent = function(evt)
           if( evt.type == evtType) 

// decorator '@on' - filters by the selector
function @on(func, selector)
      return function(evt)
        if( ) // if target element matches 
          return,evt);       // the selector call the func. 

Chain of decoratorsAs you may see both decorators simply create wrapper functions that filter the event using different criteria. Thus following statement:

@when Event.BUTTON_CLICK @on "button#add" :{...code...}

simply establishes chain of filters that ends up with the call of code that handles the event.

Syntax of decorators in TIScript is described here.