PageFlow

From Vexi

Jump to: navigation, search

Contents

Introduction

To put it tersely, org.vexi.pageflow is a display linked state machine that provides a structured way to manage asynchronous flow control in vexi applications.

What does this mean? Synchronous flow control is typically done by making use of program flow control structures, if, else, switch, while ... etc. The problem is vexi (like most sane ui environments) only has a single event thread so it is unacceptable to stop inside the current thread and wait for user input, or even rpc calls to return.

/// BAD you cannot program like this
if(waitForKey()=='x') 
 else if ...

The solution is to use a statemachine. This solves the asynchronous control flow problem and furthermore is much cleaner and clearer - the flow can be described declaratively.

Parts

Pageflow is made up of 3 parts

  • 1 holder (vexi.pageflow.holder)
  • 1 pageflow (vexi.pageflow.pageflow)
  • many views (vexi.pageflow.view)


Holder

The holder is infact very simple. It is essentially just a box that is designated as the location where the pageflow can display its views. The codebox shows a simple example where the views take up the entire frame except for the menus.

<vexi xmlns:ui="vexi://ui" xmlns:wi="vexi.widget" xmlns:pf="vexi.pageflow">
    <wi:surface />
    <ui:box>
        <wi:menu>
           ...
        </wi:menu>
        <pf:holder id="holder">
        vexi.ui.frame = thisbox;
        ...
        // initialize our pageflow
        var pf = mypageflow(vexi.js.proxy,[$holder]);
        pf.start();
    </ui:box>
</vexi>

Views

Views are even more simple. All you need to do is preapply the vexi.pageflow.view to a piece of vexi ui that you want to be displayed for a given state. Infact (currently at least) the only thing the <pf:view/> preapply does is make sure that thisbox.pageflow is set when the widget is created. Why this is useful will be explained later.

<vexi xmlns:ui="vexi://ui" xmlns:pf="vexi.pageflow">
    <pf:view/>
    <ui:box>
       ...
    </ui:box>
</vexi>


State Machine

The statemachine is declaratively described using xml. In the example we have two states that reference two different views (myviews.view1 and myviews.view2), though note that views can be reused by different states. The ':' notation to specify a template file to use as the view.

<vexi xmlns:ui="vexi://ui" xmlns="vexi.pageflow">  
   <pageflow startstate="A">
      <state name="A" view=":myviews.view1">
          <transition name="toB" next="B"/>
          <transition name="exit" next="[exit]"/>
      </state>
      <state name="B" view=":myviews.view2">
          <transition name="exit" next="[exit]"/>
      </state>
  </pageflow>

</vexi>

Inside the states we declare the possible transitions. These transitions can then be triggered by user interaction. Quite often one would want state changes to occur after the press of a button. TODO - update to reflect likely api changes.

<vexi xmlns:ui="vexi://ui" xmlns:pf="vexi.pageflow">
    <pf:view/>
    <ui:box>
       <wi:button id="toB" text="Finish"/>
       $toB.action ++= function(v) {
           //pageflow property set on box because we are a vexi.pageflow.view
           thisbox.pageflow.event = "toB";
       }
    </ui:box>
</vexi>

The effect of this is that when we launch the application we will be presented with view1. When the user presses on the button view2 will be displayed (and view1 will be closed).

Event Listenting

Typically you will want to do more than above. In the state machine you can add code to different events to perform thing such as rpc calls and processing to create the data models for the views. TODO - complete.


Reference

In transitions there are two special states

  • [self] - transition
  • [exit] - exit the statemachine

Events TODO - complete

Personal tools
wiki information