Skip to content

Commit

Permalink
[moved] timestamp to MotionObservable
Browse files Browse the repository at this point in the history
Summary: Closes #200

Reviewers: O2 Material Motion, O3 Material JavaScript platform reviewers, #material_motion, featherless

Reviewed By: O2 Material Motion, #material_motion, featherless

Subscribers: featherless

Tags: #material_motion

Differential Revision: http://codereview.cc/D3091
  • Loading branch information
appsforartists committed Apr 24, 2017
1 parent 864c97e commit aa2ca15
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 28 deletions.
82 changes: 82 additions & 0 deletions packages/core/src/operators/__tests__/timestamp.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/** @license
* Copyright 2016 - present The Material Motion Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

import { expect } from 'chai';

import {
beforeEach,
describe,
it,
} from 'mocha-sugar-free';

import {
stub,
} from 'sinon';

declare function require(name: string);

// chai really doesn't like being imported as an ES2015 module; will be fixed in v4
require('chai').use(
require('sinon-chai')
);

import {
createMockObserver,
} from 'material-motion-testing-utils';

import {
MotionObservable,
} from '../../observables/';

describe('motionObservable.timestamp',
() => {
let stream;
let mockObserver;
let listener;

beforeEach(
() => {
mockObserver = createMockObserver();
stream = new MotionObservable(mockObserver.connect);
listener = stub();
}
);

it(`should include the current time`,
() => {
stream.timestamp().subscribe(listener);

mockObserver.next(1);

const valueInLastCall = listener.lastCall.args[0];
expect(valueInLastCall.timestamp).to.be.closeTo(performance.now(), 100);
}
);

it(`should passthrough whatever it receives as "value"`,
() => {
stream.timestamp(3).subscribe(listener);

const value = [1, 2, 3];
mockObserver.next(value);

const valueInLastCall = listener.lastCall.args[0];
expect(valueInLastCall.value).to.equal(value);

}
);
}
);
10 changes: 8 additions & 2 deletions packages/core/src/operators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ import {
withThresholdRange,
} from './thresholdRange';

import {
MotionTimestampable,
withTimestamp,
} from './timestamp';

import {
MotionUpperBoundable,
withUpperBound,
Expand All @@ -132,11 +137,11 @@ export function withMotionOperators<T, S extends Constructor<Observable<T>>>(sup
return withThresholdRange(withThreshold(withRewriteRange(withRewriteTo(withRewrite(
withMerge(withInverted(withDedupe(withLog(withUpperBound(withLowerBound(
withOffsetBy(withScaledBy(withDelayBy(withDistanceFrom(withStartWith(
withIgnoreUntil(withSlidingWindow(
withIgnoreUntil(withSlidingWindow(withTimestamp(
withPluck<T, Constructor<ObservableWithFoundationalMotionOperators<T>>>(
withFoundationalMotionOperators<T, Constructor<Observable<T>>>(superclass)
)
))
)))
)))))
)))))))
))));
Expand All @@ -161,4 +166,5 @@ export * from './slidingWindow';
export * from './startWith';
export * from './threshold';
export * from './thresholdRange';
export * from './timestamp';
export * from './upperBound';
42 changes: 42 additions & 0 deletions packages/core/src/operators/timestamp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/** @license
* Copyright 2016 - present The Material Motion Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

import {
Constructor,
Dict,
MotionMappable,
ObservableWithMotionOperators,
Timestamped,
} from '../types';

export interface MotionTimestampable<T> {
timestamp(value: T): ObservableWithMotionOperators<Timestamped<T>>;
}

export function withTimestamp<T, S extends Constructor<MotionMappable<T>>>(superclass: S): S & Constructor<MotionTimestampable<T>> {
return class extends superclass implements MotionTimestampable<T> {
timestamp(value: T): ObservableWithMotionOperators<Timestamped<T>> {
return this._map(
(value: T) => (
{
value,
timestamp: performance.now()
}
)
);
}
};
}
6 changes: 6 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export {
MotionSeedable,
MotionThresholdable,
MotionThresholdRangeable,
MotionTimestampable,
MotionUpperBoundable,
MotionWindowable,
ObservableWithFoundationalMotionOperators,
Expand Down Expand Up @@ -143,6 +144,11 @@ export interface MotionElement {

export type EqualityCheck = (a: any, b: any) => boolean;

export interface Timestamped<T> {
value: T,
timestamp: number,
}

export type DragSystem = (interaction: Draggable) => MotionObservable<Point2D>;
export type SpringSystem<T extends number | Point2D> = (interaction: SpringT<T>) => MotionObservable<T>;

Expand Down
21 changes: 0 additions & 21 deletions packages/experimental-addons/src/ExperimentalMotionObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,6 @@ import {
isObservable,
} from 'material-motion';

import {
GestureRecognition,
Timestamped,
TranslationGestureRecognition,
} from './types';

/**
* MotionObservable, with experimental operators
*/
Expand Down Expand Up @@ -126,21 +120,6 @@ export class ExperimentalMotionObservable<T> extends MotionObservable<T> {
) as ExperimentalMotionObservable<T>;
}

/**
* Transforms incoming `value` into `{ value, timestamp }`, where `timestamp`
* is the number of milliseconds since `navigationStart`.
*/
withTimestamp(): ExperimentalMotionObservable<Timestamped<T>> {
return this._map(
(value: T) => (
{
value,
timestamp: performance.now()
}
)
);
}

/**
* Listens to a second stream, and replaces every value it receives from
* upstream with the latest value from the second stream.
Expand Down
5 changes: 0 additions & 5 deletions packages/experimental-addons/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,3 @@ export interface Director {
}
};
}

export interface Timestamped<T> {
value: T,
timestamp: number,
}

0 comments on commit aa2ca15

Please sign in to comment.