1 |
|
2 | export default {
|
3 |
|
4 | reads: [],
|
5 | writes: [],
|
6 | time: 1000 / 30,
|
7 | // time: 1000/60,
|
8 | pending: false,
|
9 |
|
10 | setup (options) {
|
11 | options = options || {};
|
12 | this.time = options.time || this.time;
|
13 | },
|
14 |
|
15 | tick (callback) {
|
16 | window.requestAnimationFrame(callback.bind(this, null));
|
17 | },
|
18 |
|
19 | // schedules a new read/write batch if one is not pending
|
20 | schedule () {
|
21 | if (this.pending) return;
|
22 | this.pending = true;
|
23 | this.tick(this.flush);
|
24 | },
|
25 |
|
26 | flush (time) {
|
27 | time = time || performance.now();
|
28 |
|
29 | let task;
|
30 |
|
31 | // if (data.reads === 0) {
|
32 | // while (task = this.reads.shift()) {
|
33 | //
|
34 | // if (task) {
|
35 | // task();
|
36 | // data.reads++;
|
37 | // }
|
38 | //
|
39 | // if (data.writes && data.writes === data.reads) {
|
40 | // data.writes = 0;
|
41 | // break;
|
42 | // }
|
43 | //
|
44 | // if ((performance.now() - data.time) > this.time) {
|
45 | // data.writes = 0;
|
46 | // data.time = null;
|
47 | // return this.tick(this.flush, data);
|
48 | // break;
|
49 | // }
|
50 | //
|
51 | // }
|
52 | // }
|
53 | //
|
54 | // if (data.writes === 0) {
|
55 | // while (task = this.writes.shift()) {
|
56 | //
|
57 | // if (task) {
|
58 | // task();
|
59 | // data.writes++;
|
60 | // }
|
61 | //
|
62 | // if (data.reads && data.reads === data.writes) {
|
63 | // data.reads = 0;
|
64 | // break;
|
65 | // }
|
66 | //
|
67 | // if ((performance.now() - data.time) > this.time) {
|
68 | // data.reads = 0;
|
69 | // data.time = null;
|
70 | // return this.tick(this.flush, data);
|
71 | // }
|
72 | //
|
73 | // }
|
74 | // }
|
75 |
|
76 | // while (task = this.reads.shift()) task();
|
77 | // while (task = this.writes.shift()) task();
|
78 |
|
79 | if (this.writes.length === 0) {
|
80 | while (task = this.reads.shift()) {
|
81 |
|
82 | if (task) {
|
83 | task();
|
84 | }
|
85 |
|
86 | if ((performance.now() - time) > this.time) {
|
87 | return this.tick(this.flush);
|
88 | }
|
89 |
|
90 | }
|
91 | }
|
92 |
|
93 | while (task = this.writes.shift()) {
|
94 |
|
95 | if (task) {
|
96 | task();
|
97 | }
|
98 |
|
99 | if ((performance.now() - time) > this.time) {
|
100 | return this.tick(this.flush);
|
101 | }
|
102 |
|
103 | }
|
104 |
|
105 | if (this.reads.length === 0 && this.writes.length === 0) {
|
106 | this.pending = false;
|
107 | } else if ((performance.now() - time) > this.time) {
|
108 | this.tick(this.flush);
|
109 | } else {
|
110 | this.flush(time);
|
111 | }
|
112 |
|
113 | },
|
114 |
|
115 | remove (tasks, task) {
|
116 | const index = tasks.indexOf(task);
|
117 | return !!~index && !!tasks.splice(index, 1);
|
118 | },
|
119 |
|
120 | clear (task) {
|
121 | return this.remove(this.reads, task) || this.remove(this.writes, task);
|
122 | },
|
123 |
|
124 | batch (data) {
|
125 | const self = this;
|
126 |
|
127 | if (!data) return;
|
128 | if (!data.read && !data.write) return;
|
129 |
|
130 | data.context = data.context || {};
|
131 |
|
132 | const read = function () {
|
133 | let result;
|
134 |
|
135 | if (data.read) {
|
136 | result = data.read.call(data.context, data.context);
|
137 | }
|
138 |
|
139 | if (data.write && result !== false) {
|
140 | const write = data.write.bind(data.context, data.context);
|
141 |
|
142 | self.writes.push(write);
|
143 | }
|
144 |
|
145 | };
|
146 |
|
147 | self.reads.push(read);
|
148 | self.schedule();
|
149 | }
|
150 |
|
151 | };
|