Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: experimental/conways_life/controllers/viewcontroller.js

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2011 (c) The Native Client 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.
4
5 /**
6 * @fileoverview Implement the view controller class, ViewController, that
7 * owns the Life NaCl module and wraps JavaScript bridge calls to it. This
8 * class also handles certain UI interactions, such as mouse drags and keyboard
9 * shortcuts.
10 */
11
12 goog.provide('life.controllers.ViewController');
13
14 goog.require('goog.Disposable');
15 goog.require('goog.dom');
16 goog.require('goog.events.EventTarget');
17 goog.require('goog.fx.DragEvent');
18 goog.require('goog.object');
19 goog.require('goog.style');
20 goog.require('uikit.events.Dragger');
21
22 /**
23 * Constructor for the ViewController class. This class encapsulates the
24 * Life NaCl module in a view. It also produces some UI events, such as mouse
25 * drags.
26 * @param {!Object} nativeModule The DOM element that represents a
27 * ViewController (usually the <EMBED> element that contains the NaCl
28 * module). If undefined, an error is thrown.
29 * @constructor
30 * @extends {goog.events.EventTarget}
31 */
32 life.controllers.ViewController = function(nativeModule) {
33 goog.events.EventTarget.call(this);
34 /**
35 * The element containing the Life NaCl module that corresponds to
36 * this object instance. If null or undefined, an exception is thrown.
37 * @type {Element}
38 * @private
39 */
40 if (!nativeModule) {
41 throw new Error('ViewController() requires a valid NaCl module');
42 }
43 // The container is the containing DOM element.
44 this.module_ = nativeModule;
45
46 /**
47 * The play mode. Accessed via playMode(), mutated via setPlayMode().
48 * Note that changing the play mode can cause the simulation to restart.
49 * @type {enum}
50 * @private
51 */
52 this.playMode_ = life.controllers.ViewController.PlayModes_.RANDOM_SEED;
53
54 /**
55 * Indicate whether the simulation is running.
56 * @type {bool}
57 * @private
58 */
59 this.isRunning_ = false;
60
61 /**
62 * The map of stamps. Initialized to a default stamp that produces a glider
63 * when using the "normal" Conway rules of 23/3.
64 * @type {Hash}
65 * @private
66 */
67 this.stampDictionary_ = {};
68 this.addStampWithId('***\n*..\n.*.\n', this.DEFAULT_STAMP_ID);
69
70 /**
71 * Mouse drag event object.
72 * @type {life.events.Dragger}
73 * @private
74 */
75 this.dragListener_ = new uikit.events.Dragger(nativeModule);
76 // Hook up a Dragger and listen to the drag events coming from it, then
77 // reprocess the events as Life DRAG events.
78 goog.events.listen(this.dragListener_, goog.fx.Dragger.EventType.START,
79 this.handleStartDrag_, false, this);
80 goog.events.listen(this.dragListener_, goog.fx.Dragger.EventType.END,
81 this.handleEndDrag_, false, this);
82 goog.events.listen(this.dragListener_, goog.fx.Dragger.EventType.DRAG,
83 this.handleDrag_, false, this);
84 };
85 goog.inherits(life.controllers.ViewController, goog.events.EventTarget);
86
87 /**
88 * Values for the play mode. These come from the |PLAY_MODE_SELECT| element.
89 * @enum {string}
90 * @private
91 */
92 life.controllers.ViewController.PlayModes_ = {
93 RANDOM_SEED: 'random_seed',
94 STAMP: 'stamp'
95 };
96
97 /**
98 * The id for the default stamp.
99 * @type {string}
100 */
101 life.controllers.ViewController.prototype.DEFAULT_STAMP_ID = 'default_stamp';
102
103 /**
104 * Override of disposeInternal() to unhook all the listeners and dispose
105 * of retained objects.
106 * @override
107 */
108 life.controllers.ViewController.prototype.disposeInternal = function() {
109 life.controllers.ViewController.superClass_.disposeInternal.call(this);
110 goog.events.unlisten(this.dragListener_, goog.fx.Dragger.EventType.START,
111 this.handleStartDrag_, false, this);
112 goog.events.unlisten(this.dragListener_, goog.fx.Dragger.EventType.DRAG,
113 this.handleDrag_, false, this);
114 goog.events.unlisten(this.dragListener_, goog.fx.Dragger.EventType.END,
115 this.handleEndDrag_, false, this);
116 this.dragListener_ = null;
117 this.module_ = null;
118 this.stampDictionary_ = null;
119 };
120
121 /**
122 * Simple wrapper that forwards the "clear" method to the NaCl module.
123 */
124 life.controllers.ViewController.prototype.clear = function() {
125 this.invokeMethod_('clear');
126 }
127
128 /**
129 * Return the current play mode.
130 * @return {enum} The current play mode.
131 */
132 life.controllers.ViewController.prototype.playMode = function() {
133 return this.playMode_;
134 }
135
136 /**
137 * Set the play mode to one of RANDOM_SEED or STAMP. Changing the play mode
138 * can cause the simulation to restart in the new play mode. Do nothing if the
139 * play mode is set to the current mode.
140 * @param {string} playMode The new play mode.
141 */
142 life.controllers.ViewController.prototype.setPlayMode = function(playMode) {
143 if (playMode == this.playMode_)
144 return;
145 this.playMode_ = playMode;
146 if (this.isRunning_) {
147 this.invokeMethod_('runSimulation', { mode: this.playMode_ });
148 }
149 }
150
151 /**
152 * Set the automaton rules. The rules are expressed as an object that maps
153 * birth and keep-alive rules to neighbour counts.
154 * @param {Object.<Array>} automatonRules The new rule string.
155 */
156 life.controllers.ViewController.prototype.setAutomatonRules =
157 function(automatonRules) {
158 var ruleString = [automatonRules.keepAliveRule.join(''),
159 automatonRules.birthRule.join('')].join('/');
160 this.invokeMethod_('setAutomatonRules', { rules: ruleString });
161 }
162
163 /**
164 * Add a stamp to the simulation. The stamp is expressed as a string where
165 * each character represents a cell: '*' is a live cell and '.' is a dead one.
166 * A new-line represents the end of arow of cells. See the .LIF 1.05 format
167 * for more details:
168 * http://psoup.math.wisc.edu/mcell/ca_files_formats.html
169 * If a stamp with |stampId| already exists, then it gets replaced with the
170 * new |stampDefinition|.
171 * @param {!string} stampDescription The new stamp description.
172 * @param {!string} stampId The id associated with this stamp.
173 */
174 life.controllers.ViewController.prototype.addStampWithId =
175 function(stampDescription, stampId) {
176 this.stampDictionary_[stampId] = stampDescription;
177 }
178
179 /**
180 * Set the current stamp. If a stamp with id |stampId| doesn't exist, then
181 * do nothing.
182 * @param {!string} stampDescription The new stamp description.
183 * @param {!string} stampId The id associated with this stamp.
184 * @return {bool} Success.
185 */
186 life.controllers.ViewController.prototype.selectStamp = function(stampId) {
187 if (stampId in this.stampDictionary_) {
188 this.invokeMethod_('setCurrentStamp',
189 { description: this.stampDictionary_[stampId] });
190 return true;
191 }
192 return false;
193 }
194
195 /**
196 * Return the encoded string for stamp with id |stampId|. If no such stamp
197 * exists, return null.
198 * @return {?string} The current stamp string.
199 */
200 life.controllers.ViewController.prototype.stampWithId = function(stampId) {
201 if (stampId in this.stampDictionary_)
202 return this.stampDictionary_[stampId];
203 return null;
204 }
205
206 /**
207 * Start the simulation. Does nothing if it's already running.
208 */
209 life.controllers.ViewController.prototype.run = function() {
210 this.isRunning_ = true;
211 this.invokeMethod_('runSimulation', { mode: this.playMode_ });
212 }
213
214 /**
215 * Stop the simulation. Does nothing if it's already stopped.
216 */
217 life.controllers.ViewController.prototype.stop = function() {
218 this.isRunning_ = false;
219 this.invokeMethod_('stopSimulation');
220 }
221
222
223 /**
224 * Set the stamp sound to the file pointed at by |stampSoundUrl|. For now,
225 * only .wav files are supported. If there is a currentstamp sound in effect,
226 * it will be replaced with this one.
227 * @param {!string} stampSoundUrl The Url that points to a .wav file containing
228 * the stamp sound.
229 */
230 life.controllers.ViewController.prototype.setStampSoundUrl =
231 function(stampSoundUrl) {
232 if (stampSoundUrl.length > 0) {
233 this.invokeMethod_('setStampSoundUrl', { soundUrl: stampSoundUrl });
234 }
235 }
236
237 /**
238 * Convert the coordinate system of |point| to the root window's coordinate
239 * system.
240 * @param {!goog.math.Coordinate} point The point in the coordinate system
241 * of this view.
242 * @return {goog.math.Coordinate} The converted point.
243 */
244 life.controllers.ViewController.prototype.convertPointToWindow =
245 function(point) {
246 var offset = goog.style.getFramedPageOffset(this.module_, window);
247 return goog.math.Coordinate.difference(point, offset);
248 }
249
250 /**
251 * Format a method invocation and call postMessage with the formatted method
252 * string. This calls the NaCl module with the invocation string. Note that
253 * this is an asynchronous call into the NaCl module.
254 * @param {!string} methodName The name of the method. This must match a
255 * published method name in the NaCl module.
256 * @param {?Object} parameters A dictionary that maps parameter names to
257 * values. All parameter values are passed a strings.
258 */
259 life.controllers.ViewController.prototype.invokeMethod_ =
260 function(methodName, opt_parameters) {
261 var method_invocation = methodName
262 if (opt_parameters) {
263 for (param in opt_parameters) {
264 method_invocation += ' ' + param + ':' + opt_parameters[param]
265 }
266 }
267 this.module_.postMessage(method_invocation);
268 }
269
270 /**
271 * Handle the drag START event: add a cell at the event's coordinates.
272 * @param {!goog.fx.DragEvent} dragStartEvent The START event that
273 * triggered this handler.
274 * @private
275 */
276 life.controllers.ViewController.prototype.handleStartDrag_ =
277 function(dragStartEvent) {
278 dragStartEvent.stopPropagation();
279 var point = this.convertPointToWindow(
280 new goog.math.Coordinate(dragStartEvent.clientX,
281 dragStartEvent.clientY));
282 this.invokeMethod_('putStampAtPoint', { x: point.x, y: point.y });
283 };
284
285 /**
286 * Handle the DRAG event: add a cell at the event's coordinates. If the
287 * event goes outside of the drawing area, clip it.
288 * @param {!goog.fx.DragEvent} dragEvent The DRAG event that triggered this
289 * handler.
290 * @private
291 */
292 life.controllers.ViewController.prototype.handleDrag_ = function(dragEvent) {
293 dragEvent.stopPropagation();
294 var point = this.convertPointToWindow(
295 new goog.math.Coordinate(dragEvent.clientX, dragEvent.clientY));
296 this.invokeMethod_('putStampAtPoint', { x: point.x, y: point.y });
297 };
298
299 /**
300 * Handle the drag END event: stop propagating the event.
301 * @param {!goog.fx.DragEvent} dragEndEvent The END event that triggered this
302 * handler.
303 * @private
304 */
305 life.controllers.ViewController.prototype.handleEndDrag_ =
306 function(dragEndEvent) {
307 dragEndEvent.stopPropagation();
308 };
OLDNEW
« no previous file with comments | « experimental/conways_life/controllers/stamp_panel.js ('k') | experimental/conways_life/controllers/viewcontroller_test.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698