forked from lichen-community-systems/bergson
-
Notifications
You must be signed in to change notification settings - Fork 0
/
clock.js
135 lines (114 loc) · 3.32 KB
/
clock.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
* Bergson Clocks
* http://github.com/colinbdclark/bergson
*
* Copyright 2015, Colin Clark
* Dual licensed under the MIT and GPL Version 2 licenses.
*/
/*global require, performance*/
var fluid = fluid || require("infusion"),
berg = fluid.registerNamespace("berg");
(function () {
"use strict";
/**
* Clock is the base grade for all Clocks.
*/
fluid.defaults("berg.clock", {
gradeNames: ["fluid.component"],
freq: 1, // Ticks per second.
members: {
/**
* The clock's current time, in seconds.
*/
time: 0,
/**
* The number of times per second that this clock will tick.
* This value is not guaranteed to be precise for all clocks.
*/
freq: "{that}.options.freq",
/**
* The duration, in seconds, between ticks.
* This value is not guaranteed to be precise for all clocks.
*/
tickDuration: {
expander: {
funcName: "berg.clock.calcTickDuration",
args: "{that}.freq"
}
}
},
invokers: {
start: "fluid.identity()",
tick: "fluid.notImplemented()",
stop: "fluid.identity()"
},
events: {
onTick: null
},
listeners: {
onDestroy: [
"{that}.stop()"
]
}
});
berg.clock.calcTickDuration = function (freq) {
return 1.0 / freq;
};
/**
* Offline Clock
*
* An Offline Clock tracks time relatively
* (i.e. without reference to a "real" source of time
* such as the system clock).
*
* This clock can be driven manually
* (perhaps by an offline frame or audio sample renderer)
* by invoking its tick() method.
*/
fluid.defaults("berg.clock.offline", {
gradeNames: ["berg.clock"],
invokers: {
tick: {
funcName: "berg.clock.offline.tick",
args: ["{that}"]
}
}
});
berg.clock.offline.tick = function (that) {
that.time = that.time + that.tickDuration;
that.events.onTick.fire(that.time, that.freq);
};
/**
* A Realtime Clock tracks time based on actual system time
* (i.e. performance.now)
*/
fluid.defaults("berg.clock.realtime", {
gradeNames: ["berg.clock"],
members: {
time: "@expand:berg.clock.realtime.now()"
},
invokers: {
tick: {
funcName: "berg.clock.realtime.tick",
args: ["{that}"]
}
}
});
// TODO: Remove this in favour of a direct call
// to performance.now() once Safari supports it
// in Web Workers.
berg.clock.realtime.now = function () {
return performance.now() / 1000;
};
// Terrible hack to workaround Safari's lack of
// support for performance.now().
if (typeof performance === "undefined") {
berg.clock.realtime.now = function () {
return Date.now() / 1000;
};
}
berg.clock.realtime.tick = function (that) {
that.time = berg.clock.realtime.now();
that.events.onTick.fire(that.time, that.freq);
};
})();