125 lines
16 KiB
XML
125 lines
16 KiB
XML
<svg xmlns="http://www.w3.org/2000/svg" width="740" height="520" viewBox="0 0 740 520">
|
|
<style>
|
|
/* 40s loop, 3 scenes with crossfade */
|
|
@keyframes scene1 { 0% { opacity:1 } 20% { opacity:1 } 22% { opacity:0 } 100% { opacity:0 } }
|
|
@keyframes scene2 { 0% { opacity:0 } 22% { opacity:0 } 24% { opacity:1 } 54% { opacity:1 } 56% { opacity:0 } 100% { opacity:0 } }
|
|
@keyframes scene3 { 0% { opacity:0 } 56% { opacity:0 } 58% { opacity:1 } 95% { opacity:1 } 97% { opacity:0 } 100% { opacity:0 } }
|
|
/* per-line reveals within each scene */
|
|
@keyframes s1a { 0%,1% {opacity:0} 2% {opacity:1} 21% {opacity:1} 22% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s1b { 0%,3% {opacity:0} 4% {opacity:1} 21% {opacity:1} 22% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s1c { 0%,5% {opacity:0} 6% {opacity:1} 21% {opacity:1} 22% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s1d { 0%,6% {opacity:0} 7% {opacity:1} 21% {opacity:1} 22% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s1e { 0%,7% {opacity:0} 8% {opacity:1} 21% {opacity:1} 22% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s1f { 0%,8% {opacity:0} 9% {opacity:1} 21% {opacity:1} 22% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s1g { 0%,9% {opacity:0} 10% {opacity:1} 21% {opacity:1} 22% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s1h { 0%,10% {opacity:0} 11% {opacity:1} 21% {opacity:1} 22% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s1i { 0%,11% {opacity:0} 12% {opacity:1} 21% {opacity:1} 22% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s1j { 0%,13% {opacity:0} 14% {opacity:1} 21% {opacity:1} 22% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s1k { 0%,16% {opacity:0} 17% {opacity:1} 21% {opacity:1} 22% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2a { 0%,24% {opacity:0} 25% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2b { 0%,27% {opacity:0} 28% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2c { 0%,28% {opacity:0} 29% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2d { 0%,29% {opacity:0} 30% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2e { 0%,30% {opacity:0} 31% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2f { 0%,31% {opacity:0} 32% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2g { 0%,32% {opacity:0} 33% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2h { 0%,33% {opacity:0} 34% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2i { 0%,34% {opacity:0} 35% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2j { 0%,35% {opacity:0} 36% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2k { 0%,36% {opacity:0} 37% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2l { 0%,37% {opacity:0} 38% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2m { 0%,38% {opacity:0} 39% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2n { 0%,40% {opacity:0} 41% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2o { 0%,43% {opacity:0} 44% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s2p { 0%,46% {opacity:0} 47% {opacity:1} 55% {opacity:1} 56% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3a { 0%,58% {opacity:0} 59% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3b { 0%,60% {opacity:0} 61% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3c { 0%,61% {opacity:0} 62% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3d { 0%,62% {opacity:0} 63% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3e { 0%,63% {opacity:0} 64% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3f { 0%,64% {opacity:0} 65% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3g { 0%,65% {opacity:0} 66% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3h { 0%,66% {opacity:0} 67% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3i { 0%,68% {opacity:0} 69% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3j { 0%,70% {opacity:0} 71% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3k { 0%,71% {opacity:0} 72% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3l { 0%,73% {opacity:0} 74% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3m { 0%,76% {opacity:0} 77% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3n { 0%,78% {opacity:0} 79% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3o { 0%,81% {opacity:0} 82% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3p { 0%,83% {opacity:0} 84% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3q { 0%,86% {opacity:0} 87% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes s3r { 0%,89% {opacity:0} 90% {opacity:1} 96% {opacity:1} 97% {opacity:0} 100% {opacity:0} }
|
|
@keyframes cursor { 0%,49% {opacity:1} 50%,100% {opacity:0} }
|
|
.l { font-family:'Cascadia Code','Fira Code','SF Mono','Consolas',monospace; font-size:12.5px; }
|
|
.pr { fill:#6ec06e } .cmd { fill:#58d0f0 } .fl { fill:#c0c0c0 }
|
|
.ok { fill:#6ec06e } .kw { fill:#c586c0 } .ty { fill:#4ec9b0 }
|
|
.fn { fill:#dcdcaa } .st { fill:#ce9178 } .cm { fill:#6a9955 }
|
|
.nm { fill:#b5cea8 } .op { fill:#d4d4d4 } .pp { fill:#9cdcfe }
|
|
.dm { fill:#888888 } .hl { fill:#f0c060 }
|
|
.ann { fill:#58d0f0; font-style:italic; font-size:12px }
|
|
</style>
|
|
<rect width="740" height="520" rx="8" fill="#1e1e2e"/>
|
|
<rect width="740" height="32" rx="8" fill="#2a2a3c"/>
|
|
<rect y="24" width="740" height="8" fill="#2a2a3c"/>
|
|
<circle cx="18" cy="16" r="6" fill="#f65f57"/>
|
|
<circle cx="38" cy="16" r="6" fill="#f9bf2f"/>
|
|
<circle cx="58" cy="16" r="6" fill="#30c840"/>
|
|
<text x="370" y="20" text-anchor="middle" font-family="Arial" font-size="13" fill="#888">anvil -- from zero to tested in 30 seconds</text>
|
|
|
|
<!-- SCENE 1: Create project -->
|
|
<text y="60" class="l" opacity="0" style="animation:s1a 40s infinite"><tspan x="16" class="pr">$</tspan><tspan class="cmd"> anvil new blink --board uno</tspan></text>
|
|
<text y="80" class="l" opacity="0" style="animation:s1b 40s infinite"><tspan x="16" class="ok"> create</tspan><tspan class="fl"> blink/blink/blink.ino</tspan></text>
|
|
<text y="96" class="l" opacity="0" style="animation:s1c 40s infinite"><tspan x="16" class="ok"> create</tspan><tspan class="fl"> blink/lib/hal/hal.h</tspan></text>
|
|
<text y="112" class="l" opacity="0" style="animation:s1d 40s infinite"><tspan x="16" class="ok"> create</tspan><tspan class="fl"> blink/lib/app/blink_app.h</tspan><tspan class="ann"> your code goes here</tspan></text>
|
|
<text y="128" class="l" opacity="0" style="animation:s1e 40s infinite"><tspan x="16" class="ok"> create</tspan><tspan class="fl"> blink/test/mocks/mock_hal.h, sim_hal.h</tspan></text>
|
|
<text y="144" class="l" opacity="0" style="animation:s1f 40s infinite"><tspan x="16" class="ok"> create</tspan><tspan class="fl"> blink/test/test_unit.cpp</tspan><tspan class="ann"> your tests go here</tspan></text>
|
|
<text y="160" class="l" opacity="0" style="animation:s1g 40s infinite"><tspan x="16" class="ok"> create</tspan><tspan class="fl"> blink/build.sh, upload.sh, monitor.sh, test.sh</tspan></text>
|
|
<text y="176" class="l" opacity="0" style="animation:s1h 40s infinite"><tspan x="16" class="ok"> create</tspan><tspan class="fl"> blink/.anvil.toml, .anvilignore, .gitignore</tspan></text>
|
|
<text y="196" class="l" opacity="0" style="animation:s1i 40s infinite"><tspan x="16" class="ok"> done</tspan><tspan class="fl"> Project ready! cd blink</tspan></text>
|
|
<text y="232" class="l ann" opacity="0" style="animation:s1j 40s infinite"><tspan x="16">One command. Complete project. No boilerplate to write.</tspan></text>
|
|
<text y="252" class="l ann" opacity="0" style="animation:s1k 40s infinite"><tspan x="16">Let's look at what Anvil generated...</tspan></text>
|
|
|
|
<!-- SCENE 2: The code is clean -->
|
|
<text y="60" class="l" opacity="0" style="animation:s2a 40s infinite"><tspan x="16" class="pr">$</tspan><tspan class="cmd"> cat lib/app/blink_app.h</tspan><tspan class="dm"> // what did Anvil generate?</tspan></text>
|
|
<text y="84" class="l" opacity="0" style="animation:s2b 40s infinite"><tspan x="16" class="pp">#include</tspan><tspan class="st"> "hal.h"</tspan><tspan class="dm"> // the only dependency -- no Arduino.h</tspan></text>
|
|
<text y="104" class="l" opacity="0" style="animation:s2c 40s infinite"><tspan x="16" class="kw">class</tspan><tspan class="ty"> BlinkApp</tspan><tspan class="op"> {</tspan></text>
|
|
<text y="120" class="l" opacity="0" style="animation:s2d 40s infinite"><tspan x="16" class="kw">public:</tspan></text>
|
|
<text y="136" class="l" opacity="0" style="animation:s2e 40s infinite"><tspan x="16"> </tspan><tspan class="ty">BlinkApp</tspan><tspan class="op">(</tspan><tspan class="ty">Hal</tspan><tspan class="op">* </tspan><tspan class="pp">hal</tspan><tspan class="op">) : </tspan><tspan class="pp">hal_</tspan><tspan class="op">(</tspan><tspan class="pp">hal</tspan><tspan class="op">) {}</tspan><tspan class="dm"> // real hardware OR test mock</tspan></text>
|
|
<text y="156" class="l" opacity="0" style="animation:s2f 40s infinite"><tspan x="16"> </tspan><tspan class="kw">void</tspan><tspan class="fn"> setup</tspan><tspan class="op">() {</tspan></text>
|
|
<text y="172" class="l" opacity="0" style="animation:s2g 40s infinite"><tspan x="16"> </tspan><tspan class="pp">hal_</tspan><tspan class="op">-></tspan><tspan class="fn">pinMode</tspan><tspan class="op">(</tspan><tspan class="nm">13</tspan><tspan class="op">, </tspan><tspan class="nm">OUTPUT</tspan><tspan class="op">);</tspan></text>
|
|
<text y="188" class="l" opacity="0" style="animation:s2h 40s infinite"><tspan x="16"> }</tspan></text>
|
|
<text y="204" class="l" opacity="0" style="animation:s2i 40s infinite"><tspan x="16"> </tspan><tspan class="kw">void</tspan><tspan class="fn"> loop</tspan><tspan class="op">() {</tspan></text>
|
|
<text y="220" class="l" opacity="0" style="animation:s2j 40s infinite"><tspan x="16"> </tspan><tspan class="pp">hal_</tspan><tspan class="op">-></tspan><tspan class="fn">digitalWrite</tspan><tspan class="op">(</tspan><tspan class="nm">13</tspan><tspan class="op">, </tspan><tspan class="nm">HIGH</tspan><tspan class="op">);</tspan><tspan class="dm"> // LED on</tspan></text>
|
|
<text y="236" class="l" opacity="0" style="animation:s2k 40s infinite"><tspan x="16"> </tspan><tspan class="pp">hal_</tspan><tspan class="op">-></tspan><tspan class="fn">delay</tspan><tspan class="op">(</tspan><tspan class="nm">500</tspan><tspan class="op">);</tspan></text>
|
|
<text y="252" class="l" opacity="0" style="animation:s2l 40s infinite"><tspan x="16"> </tspan><tspan class="pp">hal_</tspan><tspan class="op">-></tspan><tspan class="fn">digitalWrite</tspan><tspan class="op">(</tspan><tspan class="nm">13</tspan><tspan class="op">, </tspan><tspan class="nm">LOW</tspan><tspan class="op">);</tspan><tspan class="dm"> // LED off</tspan></text>
|
|
<text y="268" class="l" opacity="0" style="animation:s2m 40s infinite"><tspan x="16"> </tspan><tspan class="pp">hal_</tspan><tspan class="op">-></tspan><tspan class="fn">delay</tspan><tspan class="op">(</tspan><tspan class="nm">500</tspan><tspan class="op">);</tspan></text>
|
|
<text y="284" class="l" opacity="0" style="animation:s2m 40s infinite"><tspan x="16"> }</tspan></text>
|
|
<text y="300" class="l" opacity="0" style="animation:s2n 40s infinite"><tspan x="16" class="op">};</tspan></text>
|
|
<text y="332" class="l ann" opacity="0" style="animation:s2o 40s infinite"><tspan x="16">Clean C++. No hardware coupling. Change the delay, add Serial output,</tspan></text>
|
|
<text y="350" class="l ann" opacity="0" style="animation:s2p 40s infinite"><tspan x="16">read a sensor -- just edit this file. Now let's test it without a board...</tspan></text>
|
|
|
|
<!-- SCENE 3: Test it -->
|
|
<text y="60" class="l" opacity="0" style="animation:s3a 40s infinite"><tspan x="16" class="pr">$</tspan><tspan class="cmd"> cat test/test_unit.cpp</tspan><tspan class="dm"> // the student writes a quick test</tspan></text>
|
|
<text y="84" class="l" opacity="0" style="animation:s3b 40s infinite"><tspan x="16" class="pp">#include</tspan><tspan class="st"> "blink_app.h"</tspan></text>
|
|
<text y="100" class="l" opacity="0" style="animation:s3b 40s infinite"><tspan x="16" class="pp">#include</tspan><tspan class="st"> "sim_hal.h"</tspan><tspan class="dm"> // simulated Arduino -- runs on laptop</tspan></text>
|
|
<text y="120" class="l" opacity="0" style="animation:s3c 40s infinite"><tspan x="16" class="fn">TEST</tspan><tspan class="op">(BlinkTest, LedTurnsOn) {</tspan></text>
|
|
<text y="136" class="l" opacity="0" style="animation:s3d 40s infinite"><tspan x="16"> </tspan><tspan class="ty">SimHal</tspan><tspan class="pp"> hal</tspan><tspan class="op">;</tspan><tspan class="dm"> // fake hardware</tspan></text>
|
|
<text y="152" class="l" opacity="0" style="animation:s3e 40s infinite"><tspan x="16"> </tspan><tspan class="ty">BlinkApp</tspan><tspan class="pp"> app</tspan><tspan class="op">(&</tspan><tspan class="pp">hal</tspan><tspan class="op">);</tspan><tspan class="dm"> // inject it</tspan></text>
|
|
<text y="168" class="l" opacity="0" style="animation:s3f 40s infinite"><tspan x="16"> </tspan><tspan class="pp">app</tspan><tspan class="op">.</tspan><tspan class="fn">setup</tspan><tspan class="op">();</tspan></text>
|
|
<text y="184" class="l" opacity="0" style="animation:s3g 40s infinite"><tspan x="16"> </tspan><tspan class="pp">app</tspan><tspan class="op">.</tspan><tspan class="fn">loop</tspan><tspan class="op">();</tspan></text>
|
|
<text y="200" class="l" opacity="0" style="animation:s3h 40s infinite"><tspan x="16"> </tspan><tspan class="fn">EXPECT_EQ</tspan><tspan class="op">(</tspan><tspan class="pp">hal</tspan><tspan class="op">.</tspan><tspan class="fn">getPin</tspan><tspan class="op">(</tspan><tspan class="nm">13</tspan><tspan class="op">), </tspan><tspan class="nm">LOW</tspan><tspan class="op">);</tspan><tspan class="dm"> // ended on LOW after blink</tspan></text>
|
|
<text y="216" class="l" opacity="0" style="animation:s3i 40s infinite"><tspan x="16" class="op">}</tspan></text>
|
|
<text y="244" class="l" opacity="0" style="animation:s3j 40s infinite"><tspan x="16" class="pr">$</tspan><tspan class="cmd"> ./test.sh</tspan></text>
|
|
<text y="268" class="l dm" opacity="0" style="animation:s3k 40s infinite"><tspan x="16">[==========] Running 3 tests from 2 test suites.</tspan></text>
|
|
<text y="284" class="l" opacity="0" style="animation:s3l 40s infinite"><tspan x="16" class="ok">[ PASSED ]</tspan><tspan class="fl"> BlinkTest.LedTurnsOn</tspan></text>
|
|
<text y="300" class="l" opacity="0" style="animation:s3l 40s infinite"><tspan x="16" class="ok">[ PASSED ]</tspan><tspan class="fl"> BlinkTest.LedToggles</tspan></text>
|
|
<text y="316" class="l" opacity="0" style="animation:s3m 40s infinite"><tspan x="16" class="ok">[ PASSED ]</tspan><tspan class="fl"> BlinkTest.SetsPinMode</tspan></text>
|
|
<text y="336" class="l" opacity="0" style="animation:s3n 40s infinite"><tspan x="16" class="ok">[ PASSED ] 3 tests.</tspan><tspan class="hl"> (8 ms)</tspan></text>
|
|
<text y="364" class="l" opacity="0" style="animation:s3o 40s infinite"><tspan x="16" class="pr">$</tspan><tspan class="cmd"> ./upload.sh --monitor</tspan></text>
|
|
<text y="384" class="l" opacity="0" style="animation:s3p 40s infinite"><tspan x="16" class="ok">Upload complete.</tspan><tspan class="fl"> Opening serial monitor at 115200 baud.</tspan></text>
|
|
<text y="416" class="l ann" opacity="0" style="animation:s3q 40s infinite"><tspan x="16">Tests run on your laptop in milliseconds. No board needed.</tspan></text>
|
|
<text y="436" class="l ann" opacity="0" style="animation:s3r 40s infinite"><tspan x="16">Find bugs in 5 minutes instead of 2 hours staring at a serial monitor.</tspan></text>
|
|
<rect x="16" y="456" width="8" height="14" fill="#58d0f0" opacity="0" style="animation:s3r 40s infinite, cursor 1s step-end infinite"/>
|
|
</svg>
|