XForms:Model Concurrent Changes: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
(decision)
(Revised thoughts)
 
(One intermediate revision by the same user not shown)
Line 25: Line 25:
# The action
# The action
# The event ''and'' 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).
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).
Line 34: Line 32:


== Deferring What and When ==
== 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?
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?
Line 42: Line 38:
# should any event handling in the model defer concurrent events?
# should any event handling in the model defer concurrent events?
# how about "rogue" events, coming from script, etc.?
# how about "rogue" events, coming from script, etc.?
# at least also defer rebuild?
# 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"
[http://www.w3.org/TR/2006/REC-xforms-20060314/slice10.html#action-action Deferred Actions in the Spec]
 
Based on that, I believe:


I believe the spec. only meant for option 1) to happen, so I think we should go for that.
# we should defer rebuild too
# both "deferred events from action" and value-changes should be deferred


== The Event-Dispatch Queue ==
== The Event-Dispatch Queue ==


The conclusion of the above is that the model should
The conclusion of the above is that the _model_ should
# be asked to perform requests for controls directly, not through events
# be asked to perform requests for controls directly, not through events
# be responsible for dispatching events on itself
# be responsible for dispatching events on itself
Line 58: Line 62:
The nsIModelPrivateElement should expose:
The nsIModelPrivateElement should expose:
<pre>
<pre>
requestRecalculate(in boolean force);
requestRebuild();
requestRevalidate(in boolean force);
requestRecalculate();
requestRefresh(in boolean force);
requestRevalidate();
requestRefresh();
</pre>
</pre>


On a call to any of these functions the following should happen
On a call to any of these functions the following should happen
<pre>
<pre>
doRequest(aRequest, aForce) {
request...() {
  if (aForce) {
    handleRequest(aRequest);
    return;
  }
   if (gDefer) {
   if (gDefer) {
     eventQ.pushBack(aRequest);
     eventQ.pushBack(the_request);
     return;
     return;
   }
   }
   gDefer = true;
   gDefer = true;
   while (aRequest) {
 
    dispatchEventFor(aRequest);
   dispatchEventFor(the_request);
    aRequest = eventQ.popFront();
 
  // Empty the queue
  req = eventQ.popFront();
  while (req) {
    dispatchEventFor(req);
   }
   }
   gDefer = false;
   gDefer = false;
Line 83: Line 88:
</pre>
</pre>


The <code>force</code> parameter is needed for action elements that need to bypass the event mechanism.
&lt;recalculate&gt; and its friends and scripts call the functions directly (exposed in nsIXFormsModelElement), which bypasses both events and the queue.


[[User:Beaufour|Beaufour]] 04:13, 4 April 2006 (PDT)
[[User:Beaufour|Beaufour]] 02:10, 16 May 2006 (PDT)

Latest revision as of 15:45, 16 May 2006

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)