XForms:Model Concurrent Changes
Introduction
XForms 1.0 Errata E70e added a line to the Value Changed Sequence section: Perform further deferred updates as necessary Which in practice means that other updates --Concurrent Changes -- triggered by the value changed sequence must be deferred.
If it is not extremely obvious by the above, the specification is not clear on how all this should actually work. So in this document I will try to argue for how I have done it, based on my logic and participation in the working group.
The work is tracked in bug 300591
The Semantics of the Events
The first issue in all this, is how we understand the semantics of the events. The events being:
They all contain the same wording in the specification:
- Dispatched in response to: a request to ...
- The default action for this event results in the following: ...
The question is whether the event should be sent at the time of the request, or before the action is actually about to be performed. Or, put in another way: What is deferred:
- The action
- The event and the action
XXX: example?
The specification _hints_ at the former, but I think something speaks for the latter: The connection between cause and effect. If only the action is deferred, there is a "lag" between sending the event and the action being performed. This means that any action listening for the event are performed on a model state different from when the action will be performed. The could for example be a decision to cancel the event (and thus the action).
Thus, I believe that we should choose 1), and defer both the event and the action. Making the event semantic: "An advice given before performing an action".
Deferring What and When
XXX: Lots of unknowns here:
Choosing to defer events and their actions, is one step closer. Problem is which events we should defer in this way? Naturally we should defer further value changed sequences, but only those three events triggered by a value changed? How about a "rogue" recalculate request during the value changed handling? Should that be deferred too?
- how about "rogue" events, coming from script, etc.?
- should we only start deferring events on during a value change sequence, or should any event handling in the model defer concurrent events?
- at least also defer rebuild?
The Event-Dispatch Queue
The conclusion of the above is that the model should
- be asked to perform requests for controls directly, not through events
- be responsible for dispatching events on itself
- implement a queue of events/requests and handle them in FIFO order
Implementation
The nsIModelPrivateElement should expose:
requestRecalculate(in boolean force); requestRevalidate(in boolean force); requestRefresh(in boolean force);
On a call to any of these functions the following should happen
doRequest(aRequest) { if (gDefer) { eventQ.pushBack(aRequest); return; } gDefer = true; while (aRequest) { dispatchEventFor(aRequest); aRequest = eventQ.popFront(); } gDefer = false; }
Beaufour 04:13, 4 April 2006 (PDT)