summaryrefslogtreecommitdiff
path: root/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/example.txt
blob: bb92f70083d7b0cd1862abfcd75455bec61f8ca8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
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();