on master help sign in
Debugger: split module wrapping into separate function; add trace path graphics.
commit92898ac1b6ac06b65d2607bd9902fe47c9827d44 authorLaszlo Pandy <laszlo.pandy@prezi.com> dateFri 1 Nov 2013, 17:17 (13 years ago) parent139feef
1 file changed+126−49
runtime/Debugger.js+126−49
runtime/Debugger.js+126−49
@@ -3,27 +3,23 @@
33'use strict';
44
55Elm.Debugger = null;
6−Elm.debuggerInit = function(module) {
6+Elm.debuggerAttach = function(module) {
77 return {
88 make: function(runtime) {
9− Elm.Debugger = debuggerInit(module, runtime);
10− return Elm.Debugger.moduleInstance;
9+ var wrappedModule = debugModule(module, runtime);
10+ Elm.debuggerInit = function() {
11+ Elm.Debugger = debuggerInit(wrappedModule, runtime);
12+ };
13+ return wrappedModule.moduleInstance;
1114 }
1215 };
1316};
1417
15−function debuggerInit(module, runtime) {
16−
18+function debugModule(module, runtime) {
1719 var programPaused = false;
18− var allNodes = null;
19−
2020 var recordedEvents = [];
2121 var eventCounter = 0;
2222 var asyncTimers = [];
23− var initialProgramState = {
24− nodeValues: [],
25− asyncTimers: []
26− };
2723
2824 function wrapNotify(id, v) {
2925 var timestep = Date.now();
@@ -51,24 +47,131 @@ function debuggerInit(module, runtime) {
5147 recordedEvents.push({ id:id, value:v, timestep:timestep });
5248 }
5349
50+ function clearAsyncEvents() {
51+ asyncTimers.forEach(function(timer) {
52+ clearTimeout(timer.timerId);
53+ });
54+ }
55+
56+ function clearRecordedEvents() {
57+ recordedEvents = [];
58+ }
59+
60+ function getRecordedEvents() {
61+ return recordedEvents.slice();
62+ }
63+
64+ function setPaused(v) {
65+ programPaused = v;
66+ }
67+
68+ function getPaused() {
69+ return programPaused;
70+ }
71+
72+ var wrappedRuntime = {
73+ notify: wrapNotify,
74+ runDelayed: wrapRunDelayed,
75+ node: runtime.node,
76+ display: runtime.display,
77+ id: runtime.id,
78+ addListener: runtime.addListener,
79+ inputs: runtime.inputs
80+ };
81+
82+ var moduleInstance = module.make(wrappedRuntime);
83+ var moduleNodes = flattenNodes(wrappedRuntime.inputs);
84+
85+ return {
86+ moduleInstance: moduleInstance,
87+ moduleNodes: moduleNodes,
88+ initialNodeValues: saveNodeValues(moduleNodes),
89+ initialAsyncTimers: asyncTimers.slice(),
90+ // API functions
91+ clearAsyncEvents: clearAsyncEvents,
92+ clearRecordedEvents: clearRecordedEvents,
93+ getRecordedEvents: getRecordedEvents,
94+ getPaused: getPaused,
95+ setPaused: setPaused
96+ };
97+}
98+
99+function debuggerInit(debugModule, runtime) {
100+ var Signal = Elm.Signal.make(runtime);
101+ var List = Elm.List.make(runtime);
102+ var graphicsNode = debugModule.moduleInstance.main.kids[0];
103+
104+ var tracePathCanvas = document.createElement('canvas');
105+ tracePathCanvas.width = window.innerWidth;
106+ tracePathCanvas.height = window.innerHeight;
107+ tracePathCanvas.style.position = "absolute";
108+ tracePathCanvas.style.top = "0";
109+ tracePathCanvas.style.left = "0";
110+ runtime.node.parentNode.appendChild(tracePathCanvas);
111+
112+ function graphicsUpdate(currentScene) {
113+ var ctx = tracePathCanvas.getContext('2d');
114+ ctx.clearRect(0, 0, tracePathCanvas.width, tracePathCanvas.height);
115+ ctx.fillText("Debugger trace path", 20, 20);
116+
117+ function drawElement(elem) {
118+ if (elem.element.ctor == "Custom" && elem.element.type == "Collage")
119+ {
120+ List.map(drawForm)(elem.element.model.forms);
121+ }
122+ else if (elem.element.ctor == "Image")
123+ {
124+ var x = 0;
125+ var y = 0;
126+ ctx.beginPath();
127+ ctx.arc(x, y, 2, 0, 2*Math.PI);
128+ ctx.fillStyle = "grey";
129+ ctx.fill();
130+ ctx.lineWidth = 1;
131+ ctx.strokeStype = "black";
132+ ctx.stroke();
133+ }
134+ }
135+
136+ function drawForm(form) {
137+ ctx.save();
138+ ctx.scale(form.scale, form.scale);
139+ ctx.rotate(form.theta);
140+ ctx.translate(form.x, -form.y);
141+ if (form.form.ctor == "FElement")
142+ {
143+ drawElement(form.form._0);
144+ }
145+
146+ ctx.restore();
147+ }
148+
149+ ctx.save();
150+ ctx.translate(ctx.canvas.width/2, ctx.canvas.height/2);
151+ drawElement(currentScene);
152+ ctx.restore();
153+ }
154+
155+ var tracePathNode = A2(Signal.lift, graphicsUpdate, graphicsNode);
156+
54157 function resetProgram() {
55− clearAsyncEvents();
56− restoreNodeValues(allNodes, initialProgramState.nodeValues);
158+ debugModule.clearAsyncEvents();
159+ restoreNodeValues(debugModule.moduleNodes, debugModule.initialNodeValues);
57160 redrawGraphics();
58161 }
59162
60163 function restartProgram() {
61164 resetProgram();
62− recordedEvents = [];
63− initialProgramState.asyncTimers.forEach(function(timer) {
165+ debugModule.clearRecordedEvents();
166+ debugModule.initialAsyncTimers.forEach(function(timer) {
64167 var func = timer.func;
65168 func();
66169 });
67170 }
68171
69172 function stepTo(index) {
70− if (!programPaused) {
71− programPaused = true;
173+ if (!debugModule.getPaused()) {
174+ debugModule.setPaused(true);
72175 resetProgram();
73176 }
74177
@@ -95,12 +198,6 @@ function debuggerInit(module, runtime) {
95198 return recordedEvents.length - 1;
96199 }
97200
98− function clearAsyncEvents() {
99− asyncTimers.forEach(function(timer) {
100− clearTimeout(timer.timerId);
101− });
102− }
103−
104201 function doPlayback(eventList) {
105202 var x = eventList.shift();
106203 var time = x[2];
@@ -113,38 +210,18 @@ function debuggerInit(module, runtime) {
113210 }
114211
115212 function redrawGraphics() {
116− var graphicsFoldp = moduleInstance.main.kids[0];
117− graphicsFoldp.recv(Date.now(), true, moduleInstance.main.id);
213+ graphicsNode.recv(Date.now(), true, debugModule.moduleInstance.main.id);
118214 }
119215
120− var wrappedRuntime = {
121− notify: wrapNotify,
122− runDelayed: wrapRunDelayed,
123− node: runtime.node,
124− display: runtime.display,
125− id: runtime.id,
126− addListener: runtime.addListener,
127− inputs: runtime.inputs
128− };
129−
130− var moduleInstance = module.make(wrappedRuntime);
131−
132216 var elmDebugger = {
133− moduleInstance: moduleInstance,
134−
135− // debugger functions
136− reset: resetProgram,
137− restart: restartProgram,
138− getMaxSteps: getMaxSteps,
139− stepTo: stepTo
217+ reset: resetProgram,
218+ restart: restartProgram,
219+ getMaxSteps: getMaxSteps,
220+ stepTo: stepTo
140221 };
141222
142− allNodes = flattenNodes(wrappedRuntime.inputs);
143− initialProgramState.nodeValues = saveNodeValues(allNodes);
144− initialProgramState.asyncTimers = asyncTimers.slice();
145−
146223 return elmDebugger;
147−};
224+}
148225
149226
150227