var fsm; var state; var trans; // Create a new finite state machine called "Test Machine" fsm = new qx.util.finitestatemachine.Fsm("Test machine"); // State S1 state = new qx.util.finitestatemachine.State( // State name "S1", // Object with state information { // Function called on entry to this state "onentry" : function(fsm, event) { alert("Previous state: " + fsm.getPreviousState()); }; // Function called on exit from this state "onexit" : function(fsm, event) { alert("Next state: " + fsm.getNextState()); }; // Automatic actions to take place before a (possibly) new state's onentry // function is called. "autoActionsBeforeOnentry" : { // The name of a function. "setEnabled" : [ { // The parameter value(s), thus "setEnabled(true);" "parameters" : [ true ], // The function would be called on each object: // this.getObject("obj1").setEnabled(true); // this.getObject("obj2").setEnabled(true); "objects" : [ "obj1", "obj2" ] // And similarly for each object in each specified group. "groups" : [ "group1", "group2" ], } ]; "setColor" : [ { "parameters" : [ "blue" ] "groups" : [ "group3", "group4" ], "objects" : [ "obj3", "obj4" ] } ]; }; // also available, in same format as actionsBeforeOnentry: // "actionsAfterOnentry", // "actionsBeforeOnexit" // "actionsAfterOnexit" // Events handled by this state, or queued for processing by a future state "events" : { // The event type "compete" is handled by one of the transitions in this // state. The transitions will be searched in order of their addition // to the state, until the predicate for a transition returns true (or // no predicate is specified for the transition, which is an implicit // "true") That transition will be used. "complete" : qx.util.finitestatemachine.Fsm.EventHandling.PREDICATE, // The event type "interval" has two objects specified by their // "friendly name". The action when an event of type "interval" occurs // depends on which object was the target of the event. "interval" : { // If the target of the event was the object to which we have given // the friendly name "flash" then use a transition specified by name "flash" : "S1_S3_interval_flash", // If the target of the event was the object to which we have given // the friendly name "timeout", then enqueue this event for possible // processing by a future state. "timeout" : qx.util.finitestatemachine.Fsm.EventHandling.BLOCKED }, // The event type "execute", too, has two objects specified by their // "friendly name". "execute" : { // If the target of the event was the object to which we have given // the friend name "ok", search the transitions in order looking for // one where the predicate is true "ok" : qx.util.finitestatemachine.Fsm.EventHandling.PREDICATE // If the target of the event was the object to which we have given // the friendly name "restart", then enqueue this event for possible // processing by a future state. "restart" : qx.util.finitestatemachine.Fsm.EventHandling.BLOCKED } // all events other than those which are handled or blocked are ignored. }; }); // Add State S1 to the finite state machine. fsm.addState(state); // Transition from S1 to S2 due to event 1 trans = new qx.util.finitestatemachine.Transition( // Transition name "S1_S2_ev1", // Object with transition information { // return TRUE to pass "predicate" : function(fsm, event) { var type = event.getType(); if (type == "somethingWeCareAbout") { return true; } else if (type == "somethingToHandleInAnotherState") { // reattempt event delivery following state transition fsm.postponeEvent(event); // do no further transition attempts for this event for now return null; } else { return false; } }, // if event matches and predicate passes, pop the state stack and go to // the state which was found at the top of the stack. States are added to // the state stack by calling fsm.pushState() during a state's onexit // function or by a transition's action function. "nextState" : qx.util.finintestatemachine.Fsm.StateChange.POP_STATE_STACK, // action taken during transisition "action" : function(fsm, event) { // save current state so a future transition can get back to // this saved state fsm.pushState(); } }); state.addTransition(trans); // Default transition (any event): remain in current state trans = new qx.util.finitestatemachine.Transition( "S1_S1_default", { // true or undefined : always pass "predicate" : function(fsm, event) { // This predicate does not pass, and we return null to tell the finite // state machine that no additional transitions in the transition list // should be tested. (Note that the next transition is the one // explicitly called for by the "interval" event on the object with // friendly name "flash". We do not want a predicate search to find // it. return null; }, // return to current state "nextState" : qx.util.finitestatemacine.CURRENT_STATE, }); state.addTransition(trans); // Transition from S1 to S2 due to event 2. Since the previous transition // returned null in its predicate function, the only way to get to this // transition is when it is called out explicitly in the state's event list. // This one was specified for the "interval" event on the object with friendly // name "flash". trans = new qx.util.finitestatememachine.Transition( "S1_S3_interval_flash", { // No predicate or a value of 'true' means that the predicate passes as if // a predicate function returned true. "predicate" : true, // if event matches, go to this state "nextState" : "S2", // action taken during transisition "action" : function(fsm, event) { alert(this.getName() + "action function"); } }); state.addTransition(trans); // We would, of course, need to add state S2 since it is specified in a // nextState property. That is left as an exercise for the reader. // Initialize and start the machine running fsm.start();