-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.html
240 lines (203 loc) · 10.2 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
<link rel="manifest" href="/manifest.json">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="theme-color" content="#ebd9b7">
<title>Dal Segno</title>
<link rel="stylesheet" href="reset.css">
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="embed.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans|Roboto:300" rel="stylesheet">
</head>
<body>
<div class="container">
<script src="ace-builds/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script src="bundle.js"></script>
<div class="hero-container">
<h1 id="hero">Dal Segno</h1>
<img id="header-segno" src="segno.svg" alt="Dal Segno sign from music notation"/>
</div>
<h2 id="simple">
See the effect of code changes instantly
</h2>
<div class="edit-to-rewind-example">
<script type="dalsegno"
id="edit-to-rewind"
data-console="true"
data-editor="true"
data-canvas-width="400"
data-program="breakoutProgram"
data-speed="100"
data-theme="solarized_light"
>
</script>
</div>
<video class="replace-embed" loop="" preload="meta" src="http://ballingt.com/assets/dalsegnodemo1.mp4">
</video>
<p class="instructions">
Try changing a number. Can you make the ball move faster?
Try <a href="#" class="lineno-link" data-dalsegno-script-id="edit-to-rewind" data-dalsegno-lineno="4" data-dalsegno-colno="12">lines 4 and 5</a>.
For more space, <a href="http://dalsegno.ballingt.com/fullscreen/?code=breakoutProgram">go fullscreen</a>.
</p>
<p class="emphasis">Dal Segno rewinds back to the last execution of a modified function.</p>
<div class="rows">
<p>
As this program runs snapshots are saved each time a function is called.
When a user makes changes to the code, the program rewinds back to the most recent time the function that was modified was run so the changes are immediately evident.
</p>
<p>
Dal Segno means "from the sign," and is used in musical notation (where it is typically abbreviated to D.S.) to instruct a musician to repeat a section of music from an earlier point denoted by the curly little symbol with two dots shown below.
</p>
</div>
<img class="spacing-segno" src="segno.svg" alt="Dal Segno sign from music notation"/>
<h2 id="language">Language Overview</h2>
<div class="simple-example">
<script type="dalsegno"
data-console="true"
data-speed="1"
data-ast-highlight="true"
data-canvas-width="300"
data-program="simpleProgram"
>
</script>
</div>
<p class="instructions">
Try adding a method from the browser window or console, like <code>(alert "hello")</code>.
<a href="http://dalsegno.ballingt.com/fullscreen/?code=simpleProgram">Open fullscreen</a> for more space.
</p>
<div class="rows">
<p>
The language is a bit like Scheme, with the addition of a <code>(defn name (arg1 arg2 ...) body)</code> special form that defines global functions.
Calling a global function causes the interpreter state to be saved, while calling a function defined by <code>(lambda (arg1 arg2 ...) body)</code> does not.
Lists are immutable, but scopes aren't: the values referred to by variables in namespaces can be updated with <code>(set! name)</code>.
</p>
<p>
JavaScript values are accessed via name lookup: after the local and enclosing scopes are searched for a name, the interpreter checks several JavaScript objects for that name. In these examples a canvas context is included in this lookup chain for drawing, along with the JavaScript browser objects <code>window</code> and <code>console</code>, as well as objects with methods for getting mouse position and pressed keys.
</p>
</div>
<p class="emphasis">
You can read the <a href="https://github.com/thomasballinger/dalsegno#language">language documentation</a> in the readme on GitHub.
</p>
<img class="spacing-segno" src="segno.svg" alt="Dal Segno sign from music notation"/>
<h2 id="golf">Let's play golf</h2>
<div class="game-example">
<script type="dalsegno"
id="golf-example"
data-console="true"
data-speed="1000"
data-canvas-width="500"
data-program="golfProgram"
>
</script>
</div>
<video class="replace-embed" loop="" preload="meta" src="http://ballingt.com/assets/rewindlines.mp4"> </video>
<p class="instructions">
Try changing
<a href="#" class="lineno-link" data-dalsegno-script-id="golf-example" data-dalsegno-lineno="57" data-dalsegno-colno="15"><code>(fire)</code></a>
after taking a shot, or
<a href="#" class="lineno-link" data-dalsegno-script-id="golf-example" data-dalsegno-lineno="86" data-dalsegno-colno="26">
play with terrain generation</a>.
For more space <a href="http://dalsegno.ballingt.com/fullscreen/?code=golfProgram">go fullscreen</a>.
</p>
<img class="spacing-segno" src="segno.svg" alt="Dal Segno sign from music notation"/>
<h2 id="space">This game is too hard</h2>
<p class="instructions">Use spacebar and the mouse to avoid the hidden asteroids.</p>
<div class="game-example">
<script type="dalsegno"
id="space-example"
data-console="true"
data-speed="500"
data-canvas-width="500"
data-program="spaceLightProgram"
>
</script>
</div>
<p class="instructions">
Try tweaking the
<a href="#" class="lineno-link" data-dalsegno-script-id="space-example" data-dalsegno-lineno="61" data-dalsegno-colno="25">size</a>
and
<a href="#" class="lineno-link" data-dalsegno-script-id="space-example" data-dalsegno-lineno="61" data-dalsegno-colno="28">shape</a>
of the floodlight.
<a href="http://dalsegno.ballingt.com/fullscreen/?code=breakoutProgram">Open fullscreen</a> for more space.
</p>
<p class="emphasis">
Write your own at <a href="http://dalsegno.ballingt.com/fullscreen">dalsegno.ballingt.com/fullscreen</a>
</p>
<img class="spacing-segno" src="segno.svg" alt="Dal Segno sign from music notation"/>
<h2 id="stepping">Stepping through program execution</h2>
<div class="stepping-example">
<script type="dalsegno"
data-console="true"
data-speed="80"
data-editor="read-only"
data-canvas-width="500"
data-step-controls="true"
data-program="breakoutProgram"
>
</script>
</div>
<video class="replace-embed" loop="" preload="meta" src="http://ballingt.com/assets/dalsegnoStep.mp4" type="video/mp4"></video>
<p class="instructions">
Start the program then use the slider to scroll through history and step through the code forwards or backwards.
</p>
<div class="rows">
<p>
Dal Segno differs from other live-reloading systems I've seen in that it rewinds to the most recent invocation of the modified function (a state created by older code) instead of replaying the new code through from the beginning or redefining the code only for future executions, as in a REPL environment.
This provides the user with the most recent situation in which this new code might have made a difference, at the cost of putting the program in a possibly unreproducible state.
Dal Segno actually saves copies the execution state instead of replaying the program from an initial state. At the cost of some space and time, this makes seeking to given program execution state faster.
</p>
<p>
Want to use Dal Segno for something, fix it, add things to it, or find out more about it?
Let me know! I'd love to hear from you at <a href="https://twitter.com/ballingt">@ballingt</a> on Twitter or by <a href="mailto:[email protected]">email</a>. I'd like to <a href="http://ballingt.com/">write more</a> about this project and it would be very helpful for me to discuss it informally first.
Beyond state rewinding, Dal Segno has been a playground for interpreter and live programming interface ideas like friendlier runtime errors, batched drawing operations, and running a program forwards and backwards. Thanks to Mary Rose Cook for the great discussions about how to make a programming environment more interactive and discoverable that led to this project.
</p>
</div>
<iframe class="gh-button" src="http://ghbtns.com/github-btn.html?user=thomasballinger&repo=dalsegno&type=star&count=true&size=large" frameborder="0" scrolling="0" width="135px" height="30px"></iframe>
<a href="https://twitter.com/ballingt" class="twitter-follow-button" data-show-count="false">Follow @ballingt</a><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<a href="http://ballingt.com">ballingt.com</a>
<img class="spacing-segno" src="segno.svg" alt="Dal Segno sign from music notation"/>
<footer>
Segno image by <a href="https://commons.wikimedia.org/wiki/File:SegnoTeken.svg">Johannes Rössel</a>, licensed <a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en">CC BY-SA</a>
</footer>
<script>
DalSegno.findScriptTags();
var videos = Array.prototype.slice.call(document.getElementsByTagName('video'));
for (var i=0; i<videos.length; i++){
videos[i].addEventListener('click', function(e){e.target.play();});
videos[i].addEventListener('mouseenter', function(e){e.target.play();});
}
function toLineNo(el, scriptId, lineno, colno){
var embeds = DalSegno.widgets.filter(function(w){ return w.scriptId === scriptId });
if (embeds.length !== 1){
return function(){ return false; };
}
var embed = embeds[0];
lineno = parseInt(lineno);
colno = colno === undefined ? undefined : parseInt(colno);
return (function(e){
embed.editor.resize(true); // Ace editor bug may require this before nextline
embed.editor.scrollToLine(lineno, true, true, function(){});
embed.editor.gotoLine(lineno, colno);
embed.editor.focus();
e.preventDefault();
return false;
});
}
var links = Array.prototype.slice.call(document.getElementsByClassName('lineno-link'));
for (var i=0; i<links.length; i++){
var link = links[i];
var cb = toLineNo(link,
link.dataset.dalsegnoScriptId,
link.dataset.dalsegnoLineno,
link.dataset.dalsegnoColno);
link.addEventListener('click', cb);
}
var videoLinks = Array.prototype.slice.call(document.getElementsByClassName('video-link'));
</script>
</body>
</html>