Skip to content

Commit 6336df2

Browse files
author
Philip Guo
committed
more marching
1 parent 9ca63bb commit 6336df2

3 files changed

Lines changed: 122 additions & 5 deletions

File tree

edu-python.js

Lines changed: 103 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
2424
// and receives a complete execution trace, which it parses and displays to HTML.
2525

2626

27+
// set to true to use jsPlumb library to render connections between
28+
// stack and heap objects
29+
var useJsPlumbRendering = false;
30+
31+
2732
var localTesting = false; // if this is true, mock-data.js had also better be included
2833

2934

@@ -33,6 +38,11 @@ var lightLineColor = '#FFFFCC';
3338
var errorColor = '#F87D76';
3439
var visitedLineColor = '#3D58A2';
3540

41+
var lightGray = "#dddddd";
42+
var darkBlue = "#3D58A2";
43+
var pinkish = "#F15149";
44+
45+
3646
// ugh globals!
3747
var curTrace = null;
3848
var curInstr = 0;
@@ -238,8 +248,12 @@ function updateOutput() {
238248

239249
// Renders the current trace entry (curEntry) into the div named by vizDiv
240250
function renderDataStructures(curEntry, vizDiv) {
241-
renderDataStructuresVersion1(curEntry, vizDiv);
242-
//renderDataStructuresVersion2(curEntry, vizDiv);
251+
if (useJsPlumbRendering) {
252+
renderDataStructuresVersion2(curEntry, vizDiv);
253+
}
254+
else {
255+
renderDataStructuresVersion1(curEntry, vizDiv);
256+
}
243257
}
244258

245259

@@ -378,14 +392,17 @@ function renderDataStructuresVersion1(curEntry, vizDiv) {
378392
//
379393
// This version was originally created in September 2011
380394
function renderDataStructuresVersion2(curEntry, vizDiv) {
381-
//console.log(curEntry);
382-
383395
$(vizDiv).html(''); // CLEAR IT!
384396

385397
// create a tabular layout for stack and heap side-by-side
386398
// TODO: figure out how to do this using CSS in a robust way!
387399
$(vizDiv).html('<table id="stackHeapTable"><tr><td><div id="stack"></div></td><td><div id="heap"></div></td></tr></table>');
388400

401+
402+
// Key: CSS ID of the div element representing the variable
403+
// Value: CSS ID of the div element representing the value rendered in the heap
404+
connectionEndpointIDs = {};
405+
389406
// first render the stack (and global vars)
390407

391408
// render locals on stack:
@@ -442,6 +459,10 @@ function renderDataStructuresVersion2(curEntry, vizDiv) {
442459
// characters that are illegal for CSS ID's ...
443460
var varDivID = divID + '__' + varname;
444461
curTr.find("td.stackFrameValue").append('<div id="' + varDivID + '">&nbsp;</div>');
462+
463+
assert(connectionEndpointIDs[varDivID] === undefined);
464+
var heapObjID = 'heap_object_' + getObjectID(val);
465+
connectionEndpointIDs[varDivID] = heapObjID;
445466
}
446467
});
447468
}
@@ -528,6 +549,10 @@ function renderDataStructuresVersion2(curEntry, vizDiv) {
528549
// characters that are illegal for CSS ID's ...
529550
var varDivID = 'global__' + varname;
530551
curTr.find("td.stackFrameValue").append('<div id="' + varDivID + '">&nbsp;</div>');
552+
553+
assert(connectionEndpointIDs[varDivID] === undefined);
554+
var heapObjID = 'heap_object_' + getObjectID(val);
555+
connectionEndpointIDs[varDivID] = heapObjID;
531556
}
532557
}
533558
});
@@ -611,6 +636,63 @@ function renderDataStructuresVersion2(curEntry, vizDiv) {
611636

612637
// finally connect stack variables to heap objects via connectors
613638

639+
for (varID in connectionEndpointIDs) {
640+
var valueID = connectionEndpointIDs[varID];
641+
jsPlumb.connect({source: varID, target: valueID});
642+
}
643+
644+
645+
// add an on-click listener to all stack frame headers
646+
$(".stackFrameHeader").click(function() {
647+
var enclosingStackFrame = $(this).parent();
648+
var enclosingStackFrameID = enclosingStackFrame.attr('id');
649+
650+
var allConnections = jsPlumb.getConnections();
651+
for (var i = 0; i < allConnections.length; i++) {
652+
var c = allConnections[i];
653+
654+
// this is VERY VERY fragile code, since it assumes that going up
655+
// five layers of parent() calls will get you from the source end
656+
// of the connector to the enclosing stack frame
657+
var stackFrameDiv = c.source.parent().parent().parent().parent().parent();
658+
659+
// if this connector starts in the selected stack frame ...
660+
if (stackFrameDiv.attr('id') == enclosingStackFrameID) {
661+
// then HIGHLIGHT IT!
662+
c.setPaintStyle({lineWidth:2, strokeStyle: darkBlue});
663+
c.endpoints[0].setPaintStyle({fillStyle: darkBlue});
664+
c.endpoints[1].setVisible(false, true, true); // JUST set right endpoint to be invisible
665+
666+
// ... and move it to the VERY FRONT
667+
$(c.canvas).css("z-index", 1000);
668+
}
669+
else {
670+
// else unhighlight it
671+
c.setPaintStyle({lineWidth:1, strokeStyle: lightGray});
672+
c.endpoints[0].setPaintStyle({fillStyle: lightGray});
673+
c.endpoints[1].setVisible(false, true, true); // JUST set right endpoint to be invisible
674+
$(c.canvas).css("z-index", 0);
675+
}
676+
}
677+
678+
// clear everything, then just activate $(this) one ...
679+
$(".stackFrame").removeClass("selectedStackFrame");
680+
$(".stackFrameHeader").addClass("inactiveStackFrameHeader");
681+
682+
enclosingStackFrame.addClass("selectedStackFrame");
683+
$(this).removeClass("inactiveStackFrameHeader");
684+
});
685+
686+
687+
// 'click' on the top-most stack frame if available,
688+
// or on "Global variables" otherwise
689+
if (curEntry.stack_locals != undefined && curEntry.stack_locals.length) {
690+
$('#stack_header0').trigger('click');
691+
}
692+
else {
693+
$('#globals_header').trigger('click');
694+
}
695+
614696
}
615697

616698
function isPrimitiveType(obj) {
@@ -1042,11 +1124,28 @@ $(document).ready(function() {
10421124
return false;
10431125
});
10441126

1127+
$("#towersOfHanoiLink").click(function() {
1128+
$.get("example-code/towers_of_hanoi.txt", function(dat) {$("#pyInput").val(dat);});
1129+
return false;
1130+
});
1131+
10451132
$("#pwTryFinallyLink").click(function() {
10461133
$.get("example-code/wentworth_try_finally.txt", function(dat) {$("#pyInput").val(dat);});
10471134
return false;
10481135
});
10491136

1137+
if (useJsPlumbRendering) {
1138+
// set some sensible defaults
1139+
jsPlumb.Defaults.Endpoint = ["Dot", {radius:3}];
1140+
//jsPlumb.Defaults.Endpoint = ["Rectangle", {width:3, height:3}];
1141+
jsPlumb.Defaults.EndpointStyle = {fillStyle: lightGray};
1142+
jsPlumb.Defaults.Anchors = ["RightMiddle", "LeftMiddle"];
1143+
jsPlumb.Defaults.Connector = [ "Bezier", { curviness:15 }]; /* too much 'curviness' causes lines to run together */
1144+
jsPlumb.Defaults.PaintStyle = {lineWidth:1, strokeStyle: lightGray};
1145+
1146+
jsPlumb.Defaults.EndpointHoverStyle = {fillStyle: pinkish};
1147+
jsPlumb.Defaults.HoverPaintStyle = {lineWidth:2, strokeStyle: pinkish};
1148+
}
10501149

10511150
// select an example on start-up:
10521151
$("#tutorialExampleLink").trigger('click');

example-code/towers_of_hanoi.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# move a stack of n disks from stack a to stack b,
2+
# using tmp as a temporary stack
3+
def TowerOfHanoi(n, a, b, tmp):
4+
if n == 1:
5+
b.append(a.pop())
6+
else:
7+
TowerOfHanoi(n-1, a, tmp, b)
8+
b.append(a.pop())
9+
TowerOfHanoi(n-1, tmp, b, a)
10+
11+
stack1 = [5,4,3,2,1]
12+
stack2 = []
13+
stack3 = []
14+
15+
# transfer stack1 to stack3 using Tower of Hanoi rules
16+
TowerOfHanoi(len(stack1), stack1, stack3, stack2)

index.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,14 @@
7878
<a id="memoFibExampleLink" href="#">memoized fib</a> |
7979
<a id="newtonExampleLink" href="#">square root</a> |
8080
<a id="insSortExampleLink" href="#">insertion sort</a> |
81-
<a id="strtokExampleLink" href="#">tokenize</a> |
81+
<a id="strtokExampleLink" href="#">tokenize</a>
82+
<br/>
8283
<a id="filterExampleLink" href="#">filter</a> |
8384
<a id="aliasExampleLink" href="#">aliasing</a> |
8485
<a id="oopSmallExampleLink" href="#">OOP</a> |
8586
<a id="pwGcdLink" href="#">gcd</a> |
8687
<a id="pwSumListLink" href="#">sumList</a> |
88+
<a id="towersOfHanoiLink" href="#">hanoi</a> |
8789
<a id="pwTryFinallyLink" href="#">exceptions</a>
8890

8991
</p>

0 commit comments

Comments
 (0)