GPU workaround to simulate Out of Memory errors with large textures
[chromium-blink-merge.git] / native_client_sdk / src / gonacl_appengine / static / bullet / NaClAM.js
blobee59a5ea63d829d4db241223d2c896b197ea6b1f
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 function NaClAMMessage() {
6   this.header = {};
7   this.frames = new Array();
10 NaClAMMessage.prototype.reset = function() {
11   this.header = {};
12   this.frames = new Array();
15 function NaClAM(embedId) {
16   this.embedId = embedId;
17   this.requestId = 0;
18   this.message = new NaClAMMessage();
19   this.state = 0;
20   this.framesLeft = 0;
21   this.listeners_ = Object.create(null);
22   this.handleMesssage_ = this.handleMesssage_.bind(this);
25 NaClAM.prototype.enable = function() {
26   window.addEventListener('message', this.handleMesssage_, true);
29 NaClAM.prototype.disable = function() {
30   window.removeEventListener('message', this.handleMesssage_, true);
33 NaClAM.prototype.log_ = function(msg) {
34   console.log(msg);
37 NaClAM.prototype.handleMesssage_ = function(event) {
38   var STATE_WAITING_FOR_HEADER = 0;
39   var STATE_COLLECTING_FRAMES = 1;
40   if (this.state == STATE_WAITING_FOR_HEADER) {
41     var header;
42     try {
43       header = JSON.parse(String(event.data));
44     } catch (e) {
45       console.log(e);
46       console.log(event.data);
47       return;
48     }
49     // Special case our log print command
50     if (header['cmd'] == 'NaClAMPrint') {
51       this.log_(header['print'])
52         return;
53     }
54     if (typeof(header['request']) != "number") {
55       console.log('Header message requestId is not a number.');
56       return;
57     }
58     if (typeof(header['frames']) != "number") {
59       console.log('Header message frames is not a number.');
60       return;
61     }
62     this.framesLeft = header['frames'];
63     this.state = STATE_COLLECTING_FRAMES;
64     this.message.header = header;
65   } else if (this.state == STATE_COLLECTING_FRAMES) {
66     this.framesLeft--;
67     this.message.frames.push(event.data);
68   }
69   if (this.state == STATE_COLLECTING_FRAMES && this.framesLeft == 0) {
70     this.dispatchEvent(this.message);
71     this.message.reset();
72     this.state = STATE_WAITING_FOR_HEADER;
73   }
76 NaClAM.prototype.messageHeaderIsValid_ = function(header) {
77   if (header['cmd'] == undefined) {
78     console.log('NaClAM: Message header does not contain cmd.');
79     return false;
80   }
81   if (typeof(header['cmd']) != "string") {
82     console.log('NaClAm: Message cmd is not a string.');
83     return false;
84   }
85   if (header['frames'] == undefined) {
86     console.log('NaClAM: Message header does not contain frames.');
87     return false;
88   }
89   if (typeof(header['frames']) != "number") {
90     console.log('NaClAm: Message frames is not a number.');
91     return false;
92   }
93   if (header['request'] == undefined) {
94     console.log('NaClAM: Message header does not contain request.');
95     return false;
96   }
97   if (typeof(header['request']) != "number") {
98     console.log('NaClAm: Message request is not a number.');
99     return false;
100   }
101   return true;
104 NaClAM.prototype.framesIsValid_ = function(frames) {
105   var i;
106   if (!frames) {
107     // No frames.
108     return true;
109   }
110   if (Array.isArray(frames) == false) {
111     console.log('NaClAM: Frames must be an array.');
112     return false;
113   }
114   for (i = 0; i < frames.length; i++) {
115     var e = frames[i];
116     if (typeof(e) == "string") {
117       continue;
118     }
119     if ((e instanceof ArrayBuffer) == false) {
120       console.log('NaClAM: Frame is not a string or ArrayBuffer');
121       return false;
122     }
123   }
124   return true;
127 NaClAM.prototype.framesLength_ = function(frames) {
128   if (!frames) {
129     // No frames.
130     return 0;
131   }
132   return frames.length;
135 NaClAM.prototype.sendMessage = function(cmdName, arguments, frames) {
136   if (this.framesIsValid_(frames) == false) {
137     console.log('NaClAM: Not sending message because frames is invalid.');
138     return undefined;
139   }
140   var numFrames = this.framesLength_(frames);
141   this.requestId++;
142   var msgHeader = {
143     cmd: cmdName,
144     frames: numFrames,
145     request: this.requestId,
146     args: arguments
147   };
148   if (this.messageHeaderIsValid_(msgHeader) == false) {
149     console.log('NaClAM: Not sending message because header is invalid.');
150     return undefined;
151   }
152   var AM = document.getElementById(this.embedId);
153   if (!AM) {
154     console.log('NaClAM: Not sending message because Acceleration Module is not there.');
155     return undefined;
156   }
157   AM.postMessage(JSON.stringify(msgHeader));
158   var i;
159   for (i = 0; i < numFrames; i++) {
160     AM.postMessage(frames[i]);
161   }
162   return this.requestId;
166  * Adds an event listener to this Acceleration Module.
167  * @param {string} type The name of the command.
168  * @param handler The handler for the cmomand. This is called whenever the command is received.
169  */
170 NaClAM.prototype.addEventListener = function(type, handler) {
171   if (!this.listeners_) {
172     this.listeners_ = Object.create(null);
173   }
174   if (!(type in this.listeners_)) {
175     this.listeners_[type] = [handler];
176   } else {
177     var handlers = this.listeners_[type];
178     if (handlers.indexOf(handler) < 0) {
179       handlers.push(handler);
180     }
181   }
185  * Removes an event listener from this Acceleration Module.
186  * @param {string} type The name of the command.
187  * @param handler The handler for the cmomand. This is called whenever the command is received.
188  */
189 NaClAM.prototype.removeEventListener = function(type, handler) {
190   if (!this.listeners_) {
191     // No listeners
192     return;
193   }
194   if (type in this.listeners_) {
195     var handlers = this.listeners_[type];
196     var index = handlers.indexOf(handler);
197     if (index >= 0) {
198       if (handlers.length == 1) {
199         // Listeners list would be empty, delete it
200         delete this.listeners_[type];
201       } else {
202         // Remove the handler
203         handlers.splice(index, 1);
204       }
205     }
206   }
211  */
212 NaClAM.prototype.dispatchEvent = function(event) {
213   if (!this.listeners_) {
214     return true;
215   }
216   var type = event.header.cmd;
217   if (type in this.listeners_) {
218     // Make a copy to walk over
219     var handlers = this.listeners_[type].concat();
220     for (var i = 0, handler; handler = handlers[i]; i++) {
221       handler.call(this, event);
222     }
223   }