on master help sign in
Debugger: hot swapping with preserved debugger state!
ed0d84bLaszlo Pandy
runtime/Debugger.js+46−4
@@ -3,11 +3,11 @@
3'use strict';
3'use strict';
4
4
5Elm.Debugger = null;
5Elm.Debugger = null;
6−Elm.debuggerAttach = function(module) {
6+Elm.debuggerAttach = function(module, hotSwapState /* =undefined */) {
7 return {
7 return {
8 make: function(runtime) {
8 make: function(runtime) {
9 var wrappedModule = debugModule(module, runtime);
9 var wrappedModule = debugModule(module, runtime);
10− Elm.Debugger = debuggerInit(wrappedModule, runtime);
10+ Elm.Debugger = debuggerInit(wrappedModule, runtime, hotSwapState);
11 dispatchElmDebuggerInit();
11 dispatchElmDebuggerInit();
12 return wrappedModule.moduleInstance;
12 return wrappedModule.moduleInstance;
13 }
13 }
@@ -84,6 +84,14 @@ function debugModule(module, runtime) {
84 return recordedEvents[i];
84 return recordedEvents[i];
85 }
85 }
86
86
87+ function copyRecordedEvents() {
88+ return recordedEvents.slice();
89+ }
90+
91+ function loadRecordedEvents(events) {
92+ recordedEvents = events.slice();
93+ }
94+
87 function setPaused(v) {
95 function setPaused(v) {
88 programPaused = v;
96 programPaused = v;
89 if (programPaused) {
97 if (programPaused) {
@@ -125,13 +133,15 @@ function debugModule(module, runtime) {
125 clearRecordedEvents: clearRecordedEvents,
133 clearRecordedEvents: clearRecordedEvents,
126 getRecordedEventsLength: getRecordedEventsLength,
134 getRecordedEventsLength: getRecordedEventsLength,
127 getRecordedEventAt: getRecordedEventAt,
135 getRecordedEventAt: getRecordedEventAt,
136+ copyRecordedEvents: copyRecordedEvents,
137+ loadRecordedEvents: loadRecordedEvents,
128 getPaused: getPaused,
138 getPaused: getPaused,
129 setPaused: setPaused,
139 setPaused: setPaused,
130 tracePath: tracePath
140 tracePath: tracePath
131 };
141 };
132}
142}
133
143
134−function debuggerInit(debugModule, runtime) {
144+function debuggerInit(debugModule, runtime, hotSwapState /* =undefined */) {
135 var Signal = Elm.Signal.make(runtime);
145 var Signal = Elm.Signal.make(runtime);
136
146
137 var tracePathNode = A2(Signal.lift, debugModule.tracePath.graphicsUpdate, debugModule.moduleInstance.main);
147 var tracePathNode = A2(Signal.lift, debugModule.tracePath.graphicsUpdate, debugModule.moduleInstance.main);
@@ -210,13 +220,45 @@ function debuggerInit(debugModule, runtime) {
210 graphicsNode.recv(Date.now(), true, debugModule.moduleInstance.main.id);
220 graphicsNode.recv(Date.now(), true, debugModule.moduleInstance.main.id);
211 }
221 }
212
222
223+ function getHotSwapState() {
224+ if (debugModule.getPaused()) {
225+ return {
226+ recordedEvents: debugModule.copyRecordedEvents(),
227+ eventCounter: eventCounter
228+ };
229+ }
230+ else {
231+ return null;
232+ }
233+ }
234+
235+ function dispose() {
236+ var parentNode = runtime.node.parentNode;
237+ parentNode.removeChild(debugModule.tracePath.canvas);
238+ parentNode.removeChild(runtime.node);
239+ }
240+
241+ if (hotSwapState) {
242+ debugModule.setPaused(true);
243+ debugModule.loadRecordedEvents(hotSwapState.recordedEvents);
244+
245+ // draw new trace path
246+ debugModule.tracePath.startRecording();
247+ stepTo(getMaxSteps());
248+ debugModule.tracePath.stopRecording();
249+
250+ stepTo(hotSwapState.eventCounter);
251+ }
252+
213 var elmDebugger = {
253 var elmDebugger = {
214 restart: restartProgram,
254 restart: restartProgram,
215 pause: pauseProgram,
255 pause: pauseProgram,
216 kontinue: continueProgram,
256 kontinue: continueProgram,
217 getMaxSteps: getMaxSteps,
257 getMaxSteps: getMaxSteps,
218 stepTo: stepTo,
258 stepTo: stepTo,
219− getPaused: debugModule.getPaused
259+ getPaused: debugModule.getPaused,
260+ getHotSwapState: getHotSwapState,
261+ dispose: dispose
220 };
262 };
221
263
222 return elmDebugger;
264 return elmDebugger;