Skip to content

Commit

Permalink
[added] scheduler.add/removeActivityListener
Browse files Browse the repository at this point in the history
Summary:
Signature is `addActivityListener({ listener })` to be consistent with our other interfaces, like `addPlan`; though, I'm amenable to making `listener` a positional argument.  Named args feels a tad redundant in this case.

Closes #86

Reviewers: markwei, O2 Material Motion, O3 JavaScript reviewers, shyndman

Reviewed By: markwei, O2 Material Motion, O3 JavaScript reviewers, shyndman

Subscribers: shyndman, markwei

Tags: #material_motion

Differential Revision: http://codereview.cc/D1748
  • Loading branch information
appsforartists committed Oct 21, 2016
1 parent 3d33221 commit 9e1d928
Showing 1 changed file with 39 additions and 1 deletion.
40 changes: 39 additions & 1 deletion packages/runtime/src/Scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,29 @@ import {
PlanAndTarget,
} from './types';

type ActivityListener = (kwargs: { isActive: boolean }) => any;

/**
* The Scheduler is responsible for fulfilling Plans by delegating them to the
* correct Performer.
*/
export default class Scheduler {
_performerMapSelector = makeCompoundKeySelector('PerformerType', 'target');
_performerMap: Map<any, Performing> = new Map();
_activityListeners: Set<ActivityListener> = new Set();

_isActive: boolean = false;
_isActiveTokenGenerator: TokenGenerator = new TokenGenerator(
{
onTokenCountChange: this._onTokenCountChange
// Using arrow function because TypeScript doesn't support bind
// https://github.com/Microsoft/TypeScript/issues/212/
onTokenCountChange: kwargs => this._onTokenCountChange(kwargs)
}
);

/**
* If any of this scheduler's performers aren't at rest, this will be true.
*/
get isActive(): boolean {
return this._isActive;
}
Expand Down Expand Up @@ -86,7 +94,37 @@ export default class Scheduler {
performer.addPlan({ plan });
}

// For now, we're using add${ propertyName }Listener to handle observation:
// - It's simple to implement.
// - It's simple to deprecate/upgrade from. When/if we have a more
// comprehensive observation story, we just have these log a warning and
// delegate to the new thing.
// - It's easy to attach to existing libraries, e.g. RxJS's fromEventPattern.

/**
* Any function passed here will be called every time scheduler.isActive
* changes.
*/
addActivityListener({ listener }:{ listener: ActivityListener }) {
this._activityListeners.add(listener);
}

/**
* Stops notifying the given listener of changes to scheduler.isActive.
*/
removeActivityListener({ listener }:{ listener: ActivityListener }) {
this._activityListeners.delete(listener);
}

_onTokenCountChange({ count }: { count: number }) {
const wasActive = this._isActive;

this._isActive = count !== 0;

if (this._isActive !== wasActive) {
this._activityListeners.forEach(
listener => listener({ isActive: this._isActive })
);
}
}
}

0 comments on commit 9e1d928

Please sign in to comment.