XForms:Model Concurrent Changes

From MozillaWiki
Jump to: navigation, search

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:

  1. The action
  2. The event and the action

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

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?

  1. should we only start deferring events during a value change sequence
  2. should any event handling in the model defer concurrent events?
  3. how about "rogue" events, coming from script, etc.?
  4. also defer rebuild?

"Instance data changes performed by a set of actions do not result in immediate computation dependency rebuilding, recalculation, revalidate and form control refreshing until the termination of the outermost action handler" Deferred Actions in the Spec

Based on that, I believe:

  1. we should defer rebuild too
  2. both "deferred events from action" and value-changes should be deferred

The Event-Dispatch Queue

The conclusion of the above is that the _model_ should

  1. be asked to perform requests for controls directly, not through events
  2. be responsible for dispatching events on itself
  3. implement a queue of events/requests and handle them in FIFO order


Implementation

The nsIModelPrivateElement should expose:

requestRebuild();
requestRecalculate();
requestRevalidate();
requestRefresh();

On a call to any of these functions the following should happen

request...() {
  if (gDefer) {
    eventQ.pushBack(the_request);
    return;
  }
  gDefer = true;

  dispatchEventFor(the_request);

  // Empty the queue
  req = eventQ.popFront();
  while (req) {
    dispatchEventFor(req);
  }
  gDefer = false;
}

<recalculate> and its friends and scripts call the functions directly (exposed in nsIXFormsModelElement), which bypasses both events and the queue.

Beaufour 02:10, 16 May 2006 (PDT)