Commit 0585a44a authored by Adam Barth's avatar Adam Barth

Merge pull request #435 from abarth/event_duration

Convert PointerInputEvent to Duration for timestamp
parents e98ae242 7b2004b0
...@@ -8,14 +8,9 @@ export 'dart:ui' show Point; ...@@ -8,14 +8,9 @@ export 'dart:ui' show Point;
/// Base class for input events. /// Base class for input events.
class InputEvent { class InputEvent {
const InputEvent({ this.type, this.timeStamp: const Duration() });
const InputEvent({ this.type, this.timeStamp: 0.0 });
final String type; final String type;
// TODO: Should timeStamp be a DateTime object instead of double? final Duration timeStamp;
// Some client code (e.g. drag.dart) does math on the time stamp.
final double timeStamp;
} }
/// Input event representing a touch or button. /// Input event representing a touch or button.
...@@ -23,7 +18,7 @@ class PointerInputEvent extends InputEvent { ...@@ -23,7 +18,7 @@ class PointerInputEvent extends InputEvent {
const PointerInputEvent({ const PointerInputEvent({
String type, String type,
double timeStamp: 0.0, Duration timeStamp: const Duration(),
this.pointer: 0, this.pointer: 0,
this.kind, this.kind,
this.x: 0.0, this.x: 0.0,
......
...@@ -16,7 +16,7 @@ class GestureVelocity { ...@@ -16,7 +16,7 @@ class GestureVelocity {
class _Estimator { class _Estimator {
int degree; int degree;
double time; Duration time;
List<double> xCoefficients; List<double> xCoefficients;
List<double> yCoefficients; List<double> yCoefficients;
double confidence; double confidence;
...@@ -32,7 +32,7 @@ class _Estimator { ...@@ -32,7 +32,7 @@ class _Estimator {
} }
abstract class _VelocityTrackerStrategy { abstract class _VelocityTrackerStrategy {
void addMovement(double timeStamp, double x, double y); void addMovement(Duration timeStamp, double x, double y);
bool getEstimator(_Estimator estimator); bool getEstimator(_Estimator estimator);
void clear(); void clear();
} }
...@@ -45,7 +45,7 @@ enum _Weighting { ...@@ -45,7 +45,7 @@ enum _Weighting {
} }
class _Movement { class _Movement {
double eventTime = 0.0; Duration eventTime = const Duration();
ui.Point position = ui.Point.origin; ui.Point position = ui.Point.origin;
} }
...@@ -61,7 +61,7 @@ class _LeastSquaresVelocityTrackerStrategy extends _VelocityTrackerStrategy { ...@@ -61,7 +61,7 @@ class _LeastSquaresVelocityTrackerStrategy extends _VelocityTrackerStrategy {
final List<_Movement> _movements; final List<_Movement> _movements;
int _index; int _index;
void addMovement(double timeStamp, double x, double y) { void addMovement(Duration timeStamp, double x, double y) {
if (++_index == kHistorySize) if (++_index == kHistorySize)
_index = 0; _index = 0;
_Movement movement = _getMovement(_index); _Movement movement = _getMovement(_index);
...@@ -81,7 +81,7 @@ class _LeastSquaresVelocityTrackerStrategy extends _VelocityTrackerStrategy { ...@@ -81,7 +81,7 @@ class _LeastSquaresVelocityTrackerStrategy extends _VelocityTrackerStrategy {
do { do {
_Movement movement = _getMovement(index); _Movement movement = _getMovement(index);
double age = newestMovement.eventTime - movement.eventTime; double age = (newestMovement.eventTime - movement.eventTime).inMilliseconds.toDouble();
if (age > kHorizonMilliseconds) if (age > kHorizonMilliseconds)
break; break;
...@@ -143,8 +143,7 @@ class _LeastSquaresVelocityTrackerStrategy extends _VelocityTrackerStrategy { ...@@ -143,8 +143,7 @@ class _LeastSquaresVelocityTrackerStrategy extends _VelocityTrackerStrategy {
return 1.0; return 1.0;
} }
int nextIndex = (index + 1) % kHistorySize; int nextIndex = (index + 1) % kHistorySize;
double deltaMilliseconds = _movements[nextIndex].eventTime - int deltaMilliseconds = (_movements[nextIndex].eventTime - _movements[index].eventTime).inMilliseconds;
_movements[index].eventTime;
if (deltaMilliseconds < 0) if (deltaMilliseconds < 0)
return 0.5; return 0.5;
if (deltaMilliseconds < 10) if (deltaMilliseconds < 10)
...@@ -159,8 +158,7 @@ class _LeastSquaresVelocityTrackerStrategy extends _VelocityTrackerStrategy { ...@@ -159,8 +158,7 @@ class _LeastSquaresVelocityTrackerStrategy extends _VelocityTrackerStrategy {
// age 10ms: 1.0 // age 10ms: 1.0
// age 50ms: 1.0 // age 50ms: 1.0
// age 60ms: 0.5 // age 60ms: 0.5
double ageMilliseconds = _movements[_index].eventTime - int ageMilliseconds = (_movements[_index].eventTime - _movements[index].eventTime).inMilliseconds;
_movements[index].eventTime;
if (ageMilliseconds < 0) if (ageMilliseconds < 0)
return 0.5; return 0.5;
if (ageMilliseconds < 10) if (ageMilliseconds < 10)
...@@ -177,8 +175,7 @@ class _LeastSquaresVelocityTrackerStrategy extends _VelocityTrackerStrategy { ...@@ -177,8 +175,7 @@ class _LeastSquaresVelocityTrackerStrategy extends _VelocityTrackerStrategy {
// age 0ms: 1.0 // age 0ms: 1.0
// age 50ms: 1.0 // age 50ms: 1.0
// age 100ms: 0.5 // age 100ms: 0.5
double ageMilliseconds = _movements[_index].eventTime - int ageMilliseconds = (_movements[_index].eventTime - _movements[index].eventTime).inMilliseconds;
_movements[index].eventTime;
if (ageMilliseconds < 50) { if (ageMilliseconds < 50) {
return 1.0; return 1.0;
} }
...@@ -207,13 +204,13 @@ class _LeastSquaresVelocityTrackerStrategy extends _VelocityTrackerStrategy { ...@@ -207,13 +204,13 @@ class _LeastSquaresVelocityTrackerStrategy extends _VelocityTrackerStrategy {
class VelocityTracker { class VelocityTracker {
static const int kAssumePointerMoveStoppedTimeMs = 40; static const int kAssumePointerMoveStoppedTimeMs = 40;
VelocityTracker() : _lastTimeStamp = 0.0, _strategy = _createStrategy(); VelocityTracker() : _strategy = _createStrategy();
double _lastTimeStamp; Duration _lastTimeStamp = const Duration();
_VelocityTrackerStrategy _strategy; _VelocityTrackerStrategy _strategy;
void addPosition(double timeStamp, double x, double y) { void addPosition(Duration timeStamp, double x, double y) {
if ((timeStamp - _lastTimeStamp) >= kAssumePointerMoveStoppedTimeMs) if ((timeStamp - _lastTimeStamp).inMilliseconds >= kAssumePointerMoveStoppedTimeMs)
_strategy.clear(); _strategy.clear();
_lastTimeStamp = timeStamp; _lastTimeStamp = timeStamp;
_strategy.addMovement(timeStamp, x, y); _strategy.addMovement(timeStamp, x, y);
......
...@@ -90,7 +90,7 @@ class _PointerEventConverter { ...@@ -90,7 +90,7 @@ class _PointerEventConverter {
return new PointerInputEvent( return new PointerInputEvent(
type: eventType, type: eventType,
timeStamp: pointer.timeStamp.toDouble(), timeStamp: new Duration(microseconds: pointer.timeStamp),
pointer: pointerIndex, pointer: pointerIndex,
kind: _mapPointerKindToString(pointer.kind), kind: _mapPointerKindToString(pointer.kind),
x: pointer.x, x: pointer.x,
...@@ -200,11 +200,12 @@ class FlutterBinding extends HitTestTarget { ...@@ -200,11 +200,12 @@ class FlutterBinding extends HitTestTarget {
/// Stops calling listener for every event that isn't localized to a given view coordinate /// Stops calling listener for every event that isn't localized to a given view coordinate
bool removeEventListener(EventListener listener) => _eventListeners.remove(listener); bool removeEventListener(EventListener listener) => _eventListeners.remove(listener);
// TODO(abarth): The engine should give us the timeStamp in Durations.
void _handleEvent(String eventType, double timeStamp) { void _handleEvent(String eventType, double timeStamp) {
assert(eventType == 'back'); assert(eventType == 'back');
InputEvent ourEvent = new InputEvent( InputEvent ourEvent = new InputEvent(
type: eventType, type: eventType,
timeStamp: timeStamp timeStamp: new Duration(microseconds: timeStamp.round())
); );
for (EventListener listener in _eventListeners) for (EventListener listener in _eventListeners)
listener(ourEvent); listener(ourEvent);
......
...@@ -11,7 +11,7 @@ class TestPointer { ...@@ -11,7 +11,7 @@ class TestPointer {
bool isDown = false; bool isDown = false;
ui.Point location; ui.Point location;
PointerInputEvent down(ui.Point newLocation, { double timeStamp: 0.0 }) { PointerInputEvent down(ui.Point newLocation, { Duration timeStamp: const Duration() }) {
assert(!isDown); assert(!isDown);
isDown = true; isDown = true;
location = newLocation; location = newLocation;
...@@ -24,7 +24,7 @@ class TestPointer { ...@@ -24,7 +24,7 @@ class TestPointer {
); );
} }
PointerInputEvent move(ui.Point newLocation, { double timeStamp: 0.0 }) { PointerInputEvent move(ui.Point newLocation, { Duration timeStamp: const Duration() }) {
assert(isDown); assert(isDown);
ui.Offset delta = newLocation - location; ui.Offset delta = newLocation - location;
location = newLocation; location = newLocation;
...@@ -39,7 +39,7 @@ class TestPointer { ...@@ -39,7 +39,7 @@ class TestPointer {
); );
} }
PointerInputEvent up({ double timeStamp: 0.0 }) { PointerInputEvent up({ Duration timeStamp: const Duration() }) {
assert(isDown); assert(isDown);
isDown = false; isDown = false;
return new PointerInputEvent( return new PointerInputEvent(
...@@ -51,7 +51,7 @@ class TestPointer { ...@@ -51,7 +51,7 @@ class TestPointer {
); );
} }
PointerInputEvent cancel({ double timeStamp: 0.0 }) { PointerInputEvent cancel({ Duration timeStamp: const Duration() }) {
assert(isDown); assert(isDown);
isDown = false; isDown = false;
return new PointerInputEvent( return new PointerInputEvent(
......
...@@ -24,7 +24,7 @@ List<PointerInputEvent> _eventFromMap(List<Map> intermediate) { ...@@ -24,7 +24,7 @@ List<PointerInputEvent> _eventFromMap(List<Map> intermediate) {
PointerInputEvent _eventFor(Map entry) { PointerInputEvent _eventFor(Map entry) {
PointerInputEvent result = new PointerInputEvent( PointerInputEvent result = new PointerInputEvent(
type: entry['type'], type: entry['type'],
timeStamp: entry['timeStamp'], timeStamp: new Duration(milliseconds: entry['timeStamp'].round()),
pointer: entry['pointer'], pointer: entry['pointer'],
x: entry['x'], x: entry['x'],
y: entry['y'] y: entry['y']
......
...@@ -165,13 +165,13 @@ class WidgetTester { ...@@ -165,13 +165,13 @@ class WidgetTester {
final kMoveCount = 50; // Needs to be >= kHistorySize, see _LeastSquaresVelocityTrackerStrategy final kMoveCount = 50; // Needs to be >= kHistorySize, see _LeastSquaresVelocityTrackerStrategy
final double timeStampDelta = 1000.0 * offset.distance / (kMoveCount * velocity); final double timeStampDelta = 1000.0 * offset.distance / (kMoveCount * velocity);
double timeStamp = 0.0; double timeStamp = 0.0;
_dispatchEvent(p.down(startLocation, timeStamp: timeStamp), result); _dispatchEvent(p.down(startLocation, timeStamp: new Duration(milliseconds: timeStamp.round())), result);
for(int i = 0; i < kMoveCount; i++) { for(int i = 0; i < kMoveCount; i++) {
final Point location = startLocation + Offset.lerp(Offset.zero, offset, i / kMoveCount); final Point location = startLocation + Offset.lerp(Offset.zero, offset, i / kMoveCount);
_dispatchEvent(p.move(location, timeStamp: timeStamp), result); _dispatchEvent(p.move(location, timeStamp: new Duration(milliseconds: timeStamp.round())), result);
timeStamp += timeStampDelta; timeStamp += timeStampDelta;
} }
_dispatchEvent(p.up(timeStamp: timeStamp), result); _dispatchEvent(p.up(timeStamp: new Duration(milliseconds: timeStamp.round())), result);
} }
void scroll(Element element, Offset offset, { int pointer: 1 }) { void scroll(Element element, Offset offset, { int pointer: 1 }) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment