on master help sign in
Merge pull request #688 from michaelbjames/debugger
74e3a59Evan Czaplicki
runtime/Debugger.js+47−15
@@ -60,6 +60,11 @@ function debugModule(module, runtime) {
60 };
60 };
61
61
62 function wrapRunDelayed(func, delayMs) {
62 function wrapRunDelayed(func, delayMs) {
63+ if (programPaused) {
64+ // Don't push timers and such to the callback stack while we're paused.
65+ // It causes too many callbacks to be fired during unpausing.
66+ return 0;
67+ }
63 var cbObj = { func:func, delayMs:delayMs, timerId:0, executed:false };
68 var cbObj = { func:func, delayMs:delayMs, timerId:0, executed:false };
64 var timerId = setTimeout(function() {
69 var timerId = setTimeout(function() {
65 cbObj.executed = true;
70 cbObj.executed = true;
@@ -103,17 +108,21 @@ function debugModule(module, runtime) {
103 recordedEvents = events.slice();
108 recordedEvents = events.slice();
104 }
109 }
105
110
106− function setPaused(v) {
111+ function setPaused() {
107− programPaused = v;
112+ programPaused = true;
108− if (programPaused) {
109− clearAsyncCallbacks();
113+ clearAsyncCallbacks();
110− tracePath.stopRecording();
114+ tracePath.stopRecording();
111− }
115+ }
112− else {
116+
113− // executeCallbacks should only be called when continuing, not when restarting.
117+ function setContinue(position) {
118+ programPaused = false;
119+ if (position > 0) {
120+ // If we're not unpausing at the head, then we need to dump the
121+ // events that are ahead of where we're continuing.
122+ recordedEvents = recordedEvents.slice(0,position);
114− //executeCallbacks(asyncCallbacks, false);
123+ executeCallbacks(asyncCallbacks, false);
115− tracePath.startRecording();
116 }
124 }
125+ tracePath.startRecording();
117 }
126 }
118
127
119 function getPaused() {
128 function getPaused() {
@@ -158,6 +167,7 @@ function debugModule(module, runtime) {
158 loadRecordedEvents: loadRecordedEvents,
167 loadRecordedEvents: loadRecordedEvents,
159 getPaused: getPaused,
168 getPaused: getPaused,
160 setPaused: setPaused,
169 setPaused: setPaused,
170+ setContinue: setContinue,
161 tracePath: tracePath,
171 tracePath: tracePath,
162 watchTracker: watchTracker,
172 watchTracker: watchTracker,
163 };
173 };
@@ -177,25 +187,35 @@ function debuggerInit(debugModule, runtime, hotSwapState /* =undefined */) {
177 debugModule.watchTracker.clear();
187 debugModule.watchTracker.clear();
178 debugModule.tracePath.clearTraces();
188 debugModule.tracePath.clearTraces();
179 debugModule.clearRecordedEvents();
189 debugModule.clearRecordedEvents();
180− debugModule.setPaused(false);
190+ debugModule.setContinue(0);
181 executeCallbacks(debugModule.initialAsyncCallbacks, true);
191 executeCallbacks(debugModule.initialAsyncCallbacks, true);
182 }
192 }
183
193
184 function pauseProgram() {
194 function pauseProgram() {
185− debugModule.setPaused(true);
195+ debugModule.setPaused();
186 eventCounter = debugModule.getRecordedEventsLength();
196 eventCounter = debugModule.getRecordedEventsLength();
187 }
197 }
188
198
189 function continueProgram() {
199 function continueProgram() {
190 if (debugModule.getPaused())
200 if (debugModule.getPaused())
191 {
201 {
192− debugModule.setPaused(false);
202+ if(eventCounter === 0) {
203+ restartProgram();
204+ return;
205+ }
206+ resetProgram();
207+ var index = eventCounter;
208+ eventCounter = 0;
209+ debugModule.tracePath.clearTraces();
210+ debugModule.tracePath.startRecording();
211+ stepTo(index);
212+ debugModule.setContinue(eventCounter);
193 }
213 }
194 }
214 }
195
215
196 function stepTo(index) {
216 function stepTo(index) {
197 if (!debugModule.getPaused()) {
217 if (!debugModule.getPaused()) {
198− debugModule.setPaused(true);
218+ debugModule.setPaused();
199 resetProgram();
219 resetProgram();
200 }
220 }
201
221
@@ -258,7 +278,13 @@ function debuggerInit(debugModule, runtime, hotSwapState /* =undefined */) {
258 }
278 }
259
279
260 if (hotSwapState) {
280 if (hotSwapState) {
281+ // The problem is that we want to previous paused state. But
282+ // by the time JS reaches here, the old code has been swapped out
283+ // and the new modules are being generated. So we can ask the
284+ // debugging console what it thinks the pause state is and go
285+ // from there.
286+ var paused = top.debug.paused;
261− debugModule.setPaused(true);
287+ debugModule.setPaused();
262 debugModule.loadRecordedEvents(hotSwapState.recordedEvents);
288 debugModule.loadRecordedEvents(hotSwapState.recordedEvents);
263
289
264 // draw new trace path
290 // draw new trace path
@@ -267,6 +293,11 @@ function debuggerInit(debugModule, runtime, hotSwapState /* =undefined */) {
267 debugModule.tracePath.stopRecording();
293 debugModule.tracePath.stopRecording();
268
294
269 stepTo(hotSwapState.eventCounter);
295 stepTo(hotSwapState.eventCounter);
296+ if (paused) {
297+ debugModule.setPaused();
298+ } else {
299+ debugModule.setContinue(hotSwapState.eventCounter);
300+ }
270 }
301 }
271
302
272 runtime.node.parentNode.appendChild(debugModule.tracePath.canvas);
303 runtime.node.parentNode.appendChild(debugModule.tracePath.canvas);
@@ -416,6 +447,7 @@ function executeCallbacks(callbacks, reexecute) {
416 callbacks.forEach(function(timer) {
447 callbacks.forEach(function(timer) {
417 if (reexecute || !timer.executed) {
448 if (reexecute || !timer.executed) {
418 var func = timer.func;
449 var func = timer.func;
450+ timer.executed = true;
419 func();
451 func();
420 }
452 }
421 });
453 });