]> git.proxmox.com Git - sencha-touch.git/blob - src/src/TaskQueue.js
import Sencha Touch 2.4.2 source
[sencha-touch.git] / src / src / TaskQueue.js
1 /**
2 * @private
3 * Handle batch read / write of DOMs, currently used in SizeMonitor + PaintMonitor
4 */
5 Ext.define('Ext.TaskQueue', {
6 requires: 'Ext.AnimationQueue',
7
8 singleton: true,
9
10 pending: false,
11
12 mode: true,
13
14 constructor: function() {
15 this.readQueue = [];
16 this.writeQueue = [];
17
18 this.run = Ext.Function.bind(this.run, this);
19 this.watch = Ext.Function.bind(this.watch, this);
20
21 // iOS has a nasty bug which causes pending requestAnimationFrame to not release
22 // the callback when the WebView is switched back and forth from / to being background process
23 // We use a watchdog timer to workaround this, and restore the pending state correctly if this happens
24 // This timer has to be set as an interval from the very beginning and we have to keep it running for
25 // as long as the app lives, setting it later doesn't seem to work
26 if (Ext.os.is.iOS) {
27 setInterval(this.watch, 500);
28 }
29 },
30
31 requestRead: function(fn, scope, args) {
32 this.request(true);
33 this.readQueue.push(arguments);
34 },
35
36 requestWrite: function(fn, scope, args) {
37 this.request(false);
38 this.writeQueue.push(arguments);
39 },
40
41 request: function(mode) {
42 if (!this.pending) {
43 this.pendingTime = Date.now();
44 this.pending = true;
45 this.mode = mode;
46 if (mode) {
47 setTimeout(this.run, 1);
48 } else {
49 requestAnimationFrame(this.run);
50 }
51 }
52 },
53
54 watch: function() {
55 if (this.pending && Date.now() - this.pendingTime >= 500) {
56 this.run();
57 }
58 },
59
60 run: function() {
61 this.pending = false;
62
63 var readQueue = this.readQueue,
64 writeQueue = this.writeQueue,
65 request = null,
66 queue;
67
68 if (this.mode) {
69 queue = readQueue;
70
71 if (writeQueue.length > 0) {
72 request = false;
73 }
74 }
75 else {
76 queue = writeQueue;
77
78 if (readQueue.length > 0) {
79 request = true;
80 }
81 }
82
83 var tasks = queue.slice(),
84 i, ln, task, fn, scope;
85
86 queue.length = 0;
87
88 for (i = 0, ln = tasks.length; i < ln; i++) {
89 task = tasks[i];
90 fn = task[0];
91 scope = task[1];
92
93 if (typeof fn == 'string') {
94 fn = scope[fn];
95 }
96
97 if (task.length > 2) {
98 fn.apply(scope, task[2]);
99 }
100 else {
101 fn.call(scope);
102 }
103 }
104
105 tasks.length = 0;
106
107 if (request !== null) {
108 this.request(request);
109 }
110 }
111 });