Skip to content

Commit

Permalink
Sensor obects have their own a reading copies.
Browse files Browse the repository at this point in the history
Fixes w3c#152. Each Sensor instance reads the sensor readings considering its individual
frequency hint, sends 'onchange' and caches the sensor latest reading at this moment.
The Sensor's attributes return values from the cached reading.
Thus we achieve:

- appearance of a new Sensor instance with a higher frequency hint does not affect the
  'onchange' notification of the existing Sensor instances of the same type.
- consistency between the Sensor's 'onchange' notification and its attribute values.

Fixes w3c#168. A Sensor object returns reading values only in "activated" state and returns null otherwise.
  • Loading branch information
Mikhail Pozdnyakov committed May 23, 2017
1 parent 2d22842 commit 70bd09c
Showing 1 changed file with 93 additions and 3 deletions.
96 changes: 93 additions & 3 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,8 @@ with the internal slots described in the following table:
</tr>
<tr>
<td><dfn attribute for=Sensor>\[[desiredPollingFrequency]]</dfn></td>
<td>The requested polling frequency. It is initially unset.</td>
<td>The requested polling frequency for the {{Sensor}} object.
It is initially unset.</td>
</tr>
<tr>
<td><dfn attribute for=Sensor>\[[lastEventFiredAt]]</dfn></td>
Expand All @@ -762,6 +763,21 @@ with the internal slots described in the following table:
or whether the object is waiting for a new reading to do so.
It is initially `true`.</td>
</tr>
<tr>
<td><dfn attribute for=Sensor>\[[reading]]</dfn></td>
<td>A deep copy of the the latest [=sensor reading=]
for the {{Sensor}} object.
Initially, it contains [=map/entries=] with the same
[=map/keys=] as the [=map/entries=] in [=latest reading=]
[=ordered map|map=] and with all the [=map/values=] set to `null`.
</td>
</tr>
<tr>
<td><dfn attribute for=Sensor>\[[readingUpdateRequested]]</dfn></td>
<td>A boolean which indicates whether {{[[reading]]}} [=ordered map|map=]
needs to be updated after a new [=sensor reading=] was reported.
It is initially `false`.</td>
</tr>
<tr>
<td><dfn attribute for=Sensor>\[[identifyingParameters]]</dfn></td>
<td>
Expand All @@ -787,7 +803,7 @@ with the internal slots described in the following table:
### Sensor.timestamp ### {#sensor-timestamp}

The getter of the {{Sensor/timestamp!!attribute}} attribute returns
[=latest reading=]["timestamp"].
<emu-val>this</emu-val>.{{[[reading]]}}["timestamp"].

### Sensor.start() ### {#sensor-start}

Expand Down Expand Up @@ -827,7 +843,7 @@ The {{Sensor/stop()}} method must run these steps or their [=equivalent=]:
### Sensor.onchange ### {#sensor-onchange}

{{Sensor/onchange}} is an {{EventHandler}} which is called
whenever a new [=sensor reading|reading=] is available.
when <emu-val>this</emu-val>.{{[[reading]]}} is updated with the [=latest reading=] [=map/entries=].

Issue: Should this be renamed `onreading`?
Should we instead add an `ondata` {{EventHandler}} for continuous data
Expand Down Expand Up @@ -986,6 +1002,8 @@ Gets the {{Error}} object passed to {{SensorErrorEventInit}}.
: output
:: None

1. [=map/For each=] |key| → |value| of |sensor_instance|.{{[[reading]]}}.
1. [=map/Set=] |sensor_instance|.{{[[reading]]}}[|key|] to `null`.
1. Let |sensor| be the [=sensor=] associated with |sensor_instance|.
1. Remove |sensor_instance| from |sensor|'s set of [=activated Sensor objects=].
1. If |sensor|'s set of [=activated Sensor objects=] is empty,
Expand Down Expand Up @@ -1175,6 +1193,9 @@ Gets the {{Error}} object passed to {{SensorErrorEventInit}}.
value of |reading| to see if there's a change
that needs to be propagated.
1. Unset |sensor|’s [=reporting flag=].
1. [=set/For each=] |s| of |activated_sensors|,
1. Invoke the [=Report Latest Reading Updated=] abstract operation,
passing it |s| as argument.
</div>


Expand Down Expand Up @@ -1203,6 +1224,73 @@ Gets the {{Error}} object passed to {{SensorErrorEventInit}}.
</div>


<h3 dfn>Find the reporting frequency of a Sensor</h3>

<div algorithm="find the reporting frequency of a sensor">

: input
:: |sensor_instance|, a {{Sensor}} object.
: output
:: |frequency|, a [=frequency=].
1. Let |frequency| be `null`.
1. Let |f| be |sensor_instance|.{{[[desiredPollingFrequency]]}}.
1. if |f| is set,
1. set |frequency| to |f| capped by the upper and lower [=current polling frequency=]
bounds for the associated [=sensor=].
1. Otherwise,
1. user agent can assign |frequency| to an appropriate value.
1. return |frequency|.
</div>


<h3 dfn>Report Latest Reading Updated</h3>

<div algorithm="report latest reading updated">

: input
:: |sensor_instance|, a {{Sensor}} object.
: output
:: None

1. If |sensor_instance|.{{[[readingUpdateRequested]]}} is `true`,
1. Abort these steps.
1. Set |sensor_instance|.{{[[readingUpdateRequested]]}} to `true`.
1. Let |lastReportedTimestamp| be |sensor_instance|.{{[[reading]]}}["timestamp"].
1. If |lastReportedTimestamp| is not set
1. Invoke the [=Update Sensor Reading=] abstract operation, passing it |sensor_instance| as argument.
1. Abort these steps.
1. Let |reportingFrequency| be result of invoking the [=Find the reporting frequency of a Sensor=]
abstract operation.
1. If |reportingFrequency| is not set
1. Invoke the [=Update Sensor Reading=] abstract operation, passing it |sensor_instance| as argument.
1. Abort these steps.
1. Let |reportingInterval| be the result of 1 / |reportingFrequency|.
1. Let |timestampDelta| be the result of [=latest reading=]["timestamp"] - |lastReportedTimestamp|.
1. If |timestampDelta| is less than or equal to |reportingInterval|
1. Invoke the [=Update Sensor Reading=] abstract operation, passing it |sensor_instance| as argument.
1. Abort these steps.
1. Let |deferUpdateTime| be the result of |reportingInterval| - |timestampDelta|.
1. User agent must defer invoking of the [=Update Sensor Reading=] abstract operation for a period of time
equal to |deferUpdateTime|.
</div>

<h3 dfn>Update Sensor Reading</h3>

<div algorithm="update sensor reading">

: input
:: |sensor_instance|, a {{Sensor}} object.
: output
:: None

1. [=map/For each=] |key| → |value| of [=latest reading=].
1. [=map/Set=] |sensor_instance|.{{[[reading]]}}[|key|] to the corresponding
value of [=latest reading=].
1. Set |sensor_instance|.{{[[readingUpdateRequested]]}} to `false`.
1. [=Fire an event=] named "change" at |sensor_instance|.
</div>


<h3 dfn>Handle Errors</h3>

<div algorithm="handle errors">
Expand All @@ -1214,6 +1302,8 @@ Gets the {{Error}} object passed to {{SensorErrorEventInit}}.
:: None

1. Set |sensor_instance|.{{[[state]]}} to "idle".
1. [=map/For each=] |key| → |value| of |sensor_instance|.{{[[reading]]}}.
1. [=map/Set=] |sensor_instance|.{{[[reading]]}}[|key|] to `null`.
1. [=Fire an event=] named "error" at |sensor_instance| using {{SensorErrorEvent}}
with its {{SensorErrorEvent/error!!attribute}} attribute initialized to |error|.
</div>
Expand Down

0 comments on commit 70bd09c

Please sign in to comment.