summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/FiniteStateMachine.js243
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/State.js8
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/Transition.js5
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/example.txt26
4 files changed, 240 insertions, 42 deletions
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/FiniteStateMachine.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/FiniteStateMachine.js
index e1a1605c83..7c293eb76b 100644
--- a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/FiniteStateMachine.js
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/FiniteStateMachine.js
@@ -142,7 +142,7 @@ qx.OO.addProperty(
{
name : "maxSavedStates",
type : "number",
- defaultValue : 5
+ defaultValue : 2
});
/*
@@ -190,6 +190,55 @@ qx.Proto.addState = function(state)
/**
+ * Replace a state in the finite state machine. This is useful if initially
+ * "dummy" states are created which load the real state table for a series of
+ * operations (and possibly also load the gui associated with the new states
+ * at the same time). Having portions of the finite state machine and their
+ * associated gui pages loaded at run time can help prevent long delays at
+ * application start-up time.
+ *
+ * @param state {qx.util.fsm.State}
+ * An object of class qx.util.fsm.State representing a state
+ * which is to be a part of this finite state machine.
+ *
+ * @param bDispose {boolean}
+ * If <i>true</i>, then dispose the old state object. If <i>false</i>, the
+ * old state object is returned for disposing by the caller.
+ *
+ * @return {Object}
+ * The old state object if it was not disposed; otherwise null.
+ */
+qx.Proto.replaceState = function(state, bDispose)
+{
+ // Ensure that we got valid state info
+ if (! state instanceof qx.util.fsm.State)
+ {
+ throw new Error("Invalid state: not an instance of " +
+ "qx.util.fsm.State");
+ }
+
+ // Retrieve the name of this state
+ var stateName = state.getName();
+
+ // Save the old state object, so we can return it to be disposed
+ var oldState = this._states[stateName];
+
+ // Replace the old state with the new state object.
+ this._states[stateName] = state;
+
+ // Did they request that the old state be disposed?
+ if (bDispose)
+ {
+ // Yup. Mark it to be disposed.
+ oldState._needDispose;
+ }
+
+ return oldState;
+};
+
+
+
+/**
* Add an object (typically a widget) that is to be accessed during state
* transitions, to the finite state machine.
*
@@ -304,12 +353,12 @@ qx.Proto.getObject = function(friendlyName)
*
* @return {string}
* If the object has been previously registered via {@see #addObject}, then
- * a reference to the object is returned; otherwise, null.
+ * the friendly name of the object is returned; otherwise, null.
*/
qx.Proto.getFriendlyName = function(obj)
{
var hash = obj.toHashCode();
- return hash ? this.getObject(this._hashToFriendly[hash]) : null;
+ return hash ? this._hashToFriendly[hash] : null;
};
@@ -336,6 +385,83 @@ qx.Proto.getGroupObjects = function(groupName)
return a;
};
+
+/**
+ * Display all of the saved objects and their reverse mappings.
+ */
+qx.Proto.displayAllObjects = function()
+{
+ for (var friendlyName in this._friendlyToHash)
+ {
+ var hash = this._friendlyToHash[friendlyName];
+ var obj = this.getObject(friendlyName);
+ this.debug(friendlyName +
+ " => " +
+ hash);
+ this.debug(" " + hash +
+ " => " +
+ this._hashToFriendly[hash]);
+ this.debug(" " + friendlyName +
+ " => " +
+ this.getObject(friendlyName));
+ this.debug(" " + this.getObject(friendlyName) +
+ " => " +
+ this.getFriendlyName(obj));
+ }
+};
+
+
+/**
+ * Recursively display an object (as debug messages)
+ *
+ * @param obj {Object}
+ * The object to be recursively displayed
+ */
+qx.Proto.debugObject = function(obj)
+{
+ thisClass = this;
+
+ var displayObj = function(obj, level)
+ {
+ var indentStr = "";
+ for (var i = 0; i < level; i++)
+ {
+ indentStr += " ";
+ }
+
+ if (typeof(obj) != "object")
+ {
+ thisClass.debug(indentStr, obj);
+ return;
+ }
+
+ for (var prop in obj)
+ {
+ if (typeof(obj[prop]) == "object")
+ {
+ if (obj[prop] instanceof Array)
+ {
+ thisClass.debug(indentStr + prop + ": " + "Array");
+ }
+ else
+ {
+ thisClass.debug(indentStr + prop + ": " + "Object");
+ }
+
+ displayObj(obj[prop], level + 1);
+ }
+ else
+ {
+ thisClass.debug(indentStr + prop + ": " + obj[prop]);
+ }
+ }
+ }
+
+ displayObj(obj, 0);
+};
+
+
+
/**
* Start (or restart, after it has terminated) the finite state machine from
* the starting state. The starting state is defined as the first state added
@@ -389,25 +515,39 @@ qx.Proto.start = function()
/**
- * Save the current state on the saved-state stack. A future transition can
- * then provide, as its nextState value, the class constant:
+ * Save the current or previous state on the saved-state stack. A future
+ * transition can then provide, as its nextState value, the class constant:
*
* qx.util.fsm.FiniteStateMachine.StateChange.POP_STATE_STACK
*
* which will cause the next state to be whatever is at the top of the
* saved-state stack, and remove that top element from the saved-state stack.
+ *
+ * @param bCurrent {boolean}
+ * When <i>true</i>, then push the current state onto the stack. This might
+ * be used in a transition, before the state has changed. When
+ * <i>false</i>, then push the previous state onto the stack. This might be
+ * used in an on entry function to save the previous state to return to.
*/
-qx.Proto.pushState = function()
+qx.Proto.pushState = function(bCurrent)
{
// See if there's room on the state stack for a new state
- if (this.getMaxSavedStates() >= this._savedStates.length)
+ if (this._savedStates.length >= this.getMaxSavedStates())
{
// Nope. Programmer error.
throw new Error("Saved-state stack is full");
}
- // Push the current state onto the saved-state stack
- this._savedStates.push(this.getState());
+ if (bCurrent)
+ {
+ // Push the current state onto the saved-state stack
+ this._savedStates.push(this.getState());
+ }
+ else
+ {
+ // Push the previous state onto the saved-state stack
+ this._savedStates.push(this.getPreviousState());
+ }
};
@@ -427,33 +567,84 @@ qx.Proto.postponeEvent = function(event)
/**
- * Event listener for all event types in the finite state machine
+ * Copy an event
*
* @param event {qx.event.type.Event}
- * The event that was dispatched.
+ * The event to be copied
+ *
+ * @return {qx.event.type.Event}
+ * The new copy of the provided event
*/
-qx.Proto.eventListener = function(event)
+qx.Proto.copyEvent = function(event)
{
- // Events are enqueued upon receipt. Some events are then processed
- // immediately; other events get processed later. We need to allow the
- // event dispatcher to free the source event upon our return, so we'll clone
- // it and enqueue our clone. The source event can then be disposed upon our
- // return.
var e = { };
for (var prop in event)
{
e[prop] = event[prop];
}
+ return e;
+};
+
+
+/**
+ * Enqueue an event for processing
+ *
+ * @param event {qx.event.type.Event}
+ * The event to be enqueued
+ *
+ * @param bAddAtHead {boolean}
+ * If <i>true</i>, put the event at the head of the queue for immediate
+ * processing. If <i>false</i>, place the event at the tail of the queue so
+ * that it receives in-order processing.
+ */
+qx.Proto.enqueueEvent = function(event, bAddAtHead)
+{
// Add the event to the event queue
- this._eventQueue.unshift(e);
+ if (bAddAtHead)
+ {
+ // Put event at the head of the queue
+ this._eventQueue.push(event);
+ }
+ else
+ {
+ // Put event at the tail of the queue
+ this._eventQueue.unshift(event);
+ }
if (qx.Settings.getValueOfClass("qx.util.fsm.FiniteStateMachine",
"debugFlags") &
qx.util.fsm.FiniteStateMachine.DebugFlags.EVENTS)
{
- this.debug(this.getName() + ": Queued event: " + e.getType());
+ if (bAddAtHead)
+ {
+ this.debug(this.getName() + ": Pushed event: " + event.getType());
+ }
+ else
+ {
+ this.debug(this.getName() + ": Queued event: " + event.getType());
+ }
}
+};
+
+
+/**
+ * Event listener for all event types in the finite state machine
+ *
+ * @param event {qx.event.type.Event}
+ * The event that was dispatched.
+ */
+qx.Proto.eventListener = function(event)
+{
+ // Events are enqueued upon receipt. Some events are then processed
+ // immediately; other events get processed later. We need to allow the
+ // event dispatcher to free the source event upon our return, so we'll clone
+ // it and enqueue our clone. The source event can then be disposed upon our
+ // return.
+ var e = this.copyEvent(event);
+
+ // Enqueue the new event on the tail of the queue
+ this.enqueueEvent(e, false);
// Process events
this._processEvents();
@@ -566,7 +757,6 @@ qx.Proto._run = function(event)
return;
}
-
// We might have found a constant (PREDICATE or BLOCKED) or an object with
// each property name being the friendly name of a saved object, and the
// property value being one of the constants (PREDICATE or BLOCKED).
@@ -678,14 +868,14 @@ qx.Proto._run = function(event)
case qx.util.fsm.FiniteStateMachine.StateChange.POP_STATE_STACK:
// Switch to the state at the top of the state stack.
- if (this._stateStack.length == 0)
+ if (this._savedStates.length == 0)
{
throw new Error("Attempt to transition to POP_STATE_STACK " +
"while state stack is empty.");
}
// Pop the state stack to retrieve the state to transition to
- nextState = this._stateStack.pop();
+ nextState = this._savedStates.pop();
this.setNextState(nextState);
break;
@@ -738,7 +928,14 @@ qx.Proto._run = function(event)
{
this.debug(this.getName() + "#" + thisState + "#autoActionsAfterOnexit");
}
- currentState.getAutoActionsAfterOnentry()(this);
+ currentState.getAutoActionsAfterOnexit()(this);
+
+ // If this state has been replaced and we're supposed to dispose it...
+ if (currentState._needDispose)
+ {
+ // ... then dispose it now that it's no longer in use
+ currentState.dispose();
+ }
// Reset currentState to the new state object
currentState = this._states[this.getNextState()];
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/State.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/State.js
index a61d27ff24..fc054e304a 100644
--- a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/State.js
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/State.js
@@ -70,7 +70,7 @@
*
* autoActionsBeforeOnentry -
* autoActionsAfterOnentry -
- * auutoActionsBeforeOnexit -
+ * autoActionsBeforeOnexit -
* autoActionsAfterOnexit -
* Automatic actions which take place at the time specified by the
* property name. In all cases, the action takes place immediately
@@ -181,11 +181,11 @@ function(stateName, stateInfo)
break;
case "autoActionsBeforeOnexit":
- this.setAutoActionsBeforeOnentry(stateInfo[field]);
+ this.setAutoActionsBeforeOnexit(stateInfo[field]);
break;
- case "autoActionsBeforeOnexit":
- this.setAutoActionsBeforeOnentry(stateInfo[field]);
+ case "autoActionsAfterOnexit":
+ this.setAutoActionsAfterOnexit(stateInfo[field]);
break;
case "events":
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/Transition.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/Transition.js
index 3d13324999..e417e23298 100644
--- a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/Transition.js
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/Transition.js
@@ -86,7 +86,7 @@
* - One of the constants:
* - qx.util.fsm.FiniteStateMachine.StateChange.CURRENT_STATE:
* Remain in whatever is the current state
- * - qx.util.fsm.FiniteStateMachine.StateChange.PREVIOUS_STATE:
+ * - qx.util.fsm.FiniteStateMachine.StateChange.POP_STATE_STACK:
* Transition to the state at the top of the saved-state stack,
* and remove the top element from the saved-state stack.
* Elements are added to the saved-state stack using
@@ -308,7 +308,8 @@ qx.Proto._checkNextState = function(propValue, propData)
switch(propValue)
{
case qx.util.fsm.FiniteStateMachine.StateChange.CURRENT_STATE:
- case qx.util.fsm.FiniteStateMachine.StateChange.PREVIOUS_STATE:
+ case qx.util.fsm.FiniteStateMachine.StateChange.POP_STATE_STACK:
+ case qx.util.fsm.FiniteStateMachine.StateChange.TERMINATE:
return propValue;
default:
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/example.txt b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/example.txt
index bb92f70083..35e8282afe 100644
--- a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/example.txt
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/example.txt
@@ -3,10 +3,10 @@ var state;
var trans;
// Create a new finite state machine called "Test Machine"
-fsm = new qx.util.finitestatemachine.Fsm("Test machine");
+fsm = new qx.util.fsm.FiniteStateMachine("Test machine");
// State S1
-state = new qx.util.finitestatemachine.State(
+state = new qx.util.fsm.State(
// State name
"S1",
@@ -58,9 +58,9 @@ state = new qx.util.finitestatemachine.State(
};
// also available, in same format as actionsBeforeOnentry:
- // "actionsAfterOnentry",
- // "actionsBeforeOnexit"
- // "actionsAfterOnexit"
+ // "autoActionsAfterOnentry",
+ // "autoActionsBeforeOnexit"
+ // "autoActionsAfterOnexit"
// Events handled by this state, or queued for processing by a future state
"events" :
@@ -70,7 +70,7 @@ state = new qx.util.finitestatemachine.State(
// 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,
+ "complete" : qx.util.fsm.FiniteStateMachine.EventHandling.PREDICATE,
// The event type "interval" has two objects specified by their
// "friendly name". The action when an event of type "interval" occurs
@@ -84,7 +84,7 @@ state = new qx.util.finitestatemachine.State(
// 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
+ "timeout" : qx.util.fsm.FiniteStateMachine.EventHandling.BLOCKED
},
// The event type "execute", too, has two objects specified by their
@@ -94,12 +94,12 @@ state = new qx.util.finitestatemachine.State(
// 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
+ "ok" : qx.util.fsm.FiniteStateMachine.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
+ "restart" : qx.util.fsm.FiniteStateMachine.EventHandling.BLOCKED
}
// all events other than those which are handled or blocked are ignored.
@@ -110,7 +110,7 @@ state = new qx.util.finitestatemachine.State(
fsm.addState(state);
// Transition from S1 to S2 due to event 1
-trans = new qx.util.finitestatemachine.Transition(
+trans = new qx.util.fsm.Transition(
// Transition name
"S1_S2_ev1",
@@ -143,7 +143,7 @@ trans = new qx.util.finitestatemachine.Transition(
// 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,
+ "nextState" : qx.util.fsm.FiniteStateMachine.StateChange..POP_STATE_STACK,
// action taken during transisition
"action" :
@@ -157,7 +157,7 @@ trans = new qx.util.finitestatemachine.Transition(
state.addTransition(trans);
// Default transition (any event): remain in current state
-trans = new qx.util.finitestatemachine.Transition(
+trans = new qx.util.fsm.Transition(
"S1_S1_default",
{
// true or undefined : always pass
@@ -174,7 +174,7 @@ trans = new qx.util.finitestatemachine.Transition(
},
// return to current state
- "nextState" : qx.util.finitestatemacine.CURRENT_STATE,
+ "nextState" : qx.util.fsm.FiniteStateMachine.StateChange.CURRENT_STATE,
});
state.addTransition(trans);