New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support running Turtle logic in the browser via WebAssembly #53
Closed
Closed
Changes from all commits
Commits
Show all changes
46 commits
Select commit
Hold shift + click to select a range
e5056ef
Introduce RenderStrategy trait.
marshallpierce 976d5f8
Get things compiling with wasm32.
marshallpierce c51d470
Rename features/modules to be more representative of what they do
marshallpierce 4e6bca8
Make Renderer (mostly) generic over piston Graphics implementations.
marshallpierce f80a4a7
Pull render loop out of Renderer into Server.
marshallpierce 681eb36
Use clock abstraction because we can't use std::time in wasm
marshallpierce f9c1fea
WIP: turtle logic can run, but no rendering yet.
marshallpierce 98caae5
Introduce a run_turtle! macro so we can then have alternate entry points
marshallpierce e0bf434
Move messenger inside desktop
marshallpierce 121d316
Drawing background color works.
marshallpierce cb08af9
Get random number generation working via the browser's Math.random
marshallpierce 8082535
Running the randomcolors example will at least render the final backg…
marshallpierce 6e60518
Run wasm in a WebWorker and copy the buffer each time a canvas update…
marshallpierce db18721
Update canvas notes
marshallpierce 6cdaab0
Let the user run any example from canvas.html
marshallpierce 280bd9b
Remove re-exported random that depends on thread_rng and expose random
marshallpierce 9196dc9
Render the corners of trinagles
marshallpierce da18b5f
Add another env function for floating point mod
marshallpierce 2d503d7
Move event helper function into server since it's only used there
marshallpierce 8920e3d
Rough but workable triangle rendering
marshallpierce 8efb285
Fix silly triangle vertex indexing bug
marshallpierce bbfe786
Update instructions
marshallpierce 65988eb
Load pixel array every time to tolerate heap resizing
marshallpierce f9c898b
Use turtle-supplied rng when generating maze
marshallpierce 23dca11
Get tests passing (though doc tests are still failing)
marshallpierce 997357e
Merge commit 'e58c6e2' into wasm
marshallpierce 3aec325
Merge commit 'fcd68fc' into wasm
marshallpierce 7d13ae0
Fix newly merged unit test
marshallpierce f4eba8a
Merge commit 'cd54686' into wasm
marshallpierce 7a61384
Fix the first few doc tests to not create a Turtle.
marshallpierce fbea89a
Fix the rest of the doc tests.
marshallpierce 259c102
Merge commit '5db76f7' into wasm
marshallpierce 36effed
Merge commit '5e345e4' into wasm
marshallpierce 3a90e00
Merge commit 'c61192d' into wasm
marshallpierce b49a2ee
Merge commit 'd26ad14' into wasm
marshallpierce 81f8a85
Merge commit 'b29c274' into wasm
marshallpierce 954a094
Merge commit '90214a8' into wasm
marshallpierce 854c191
Merge commit '0f8519d' into wasm
marshallpierce 74c19ec
Merge commit 'f60dc49' into wasm
marshallpierce b40b5d0
Merge commit '74fd197' into wasm
marshallpierce a875850
Merge commit 'c741084' into wasm
marshallpierce e67d863
Merge branch 'master' into wasm
marshallpierce a4f4d3b
Move debug_log out of Runtime -- not exposed via Turtle so no need fo…
marshallpierce 83a86c2
Merge commit 'baa6021' into wasm
marshallpierce e040f5d
Merge commit 'b223b21' into wasm
marshallpierce 6642ff8
Remove stray comment
marshallpierce File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,3 +25,6 @@ _site/ | |
.jekyll-metadata | ||
|
||
# End of https://www.gitignore.io/api/jekyll | ||
|
||
.idea | ||
*.iml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
Turtle for the web! | ||
|
||
# Setup | ||
|
||
- `rustup update` | ||
- `rustup target add wasm32-unknown-unknown --toolchain nightly` | ||
|
||
# Building | ||
|
||
To build wasm files for all examples, run: | ||
|
||
``` | ||
find . -name '*.wasm' -delete && cargo +nightly build \ | ||
--no-default-features --features=canvas \ | ||
--target=wasm32-unknown-unknown --release \ | ||
--examples | ||
|
||
``` | ||
|
||
Cargo doesn't seem very smart about updating the `.wasm` file, so we always delete it. | ||
|
||
Once the `.wasm` file is built, run a basic web server (like `python -m SimpleHTTPServer 9000`) and open [http://localhost:9000/canvas.html](http://localhost:9000/canvas.html). | ||
|
||
# Architecture | ||
|
||
On a desktop OS, Turtle uses a separate process to handle rendering and turtle state. This allows the turtle control logic to take over the main thread, which in turn allows a convenient programming model: the user provides `main()`, and as long as Turtle initialization is done right, everything proceeds fine. Rendering commands, etc, are done via stdin/stdout between the control process and render process. | ||
|
||
On the web, we don't have the built-in start point of `main()`, so control flow will have to be different. Rendering can still be done with Piston's abstraction, but we need to render to a `<canvas>`, so we need a `Graphics` implementation that writes to an RGBA pixel buffer. | ||
|
||
The Rust logic runs in a Worker and periodically sends copies of the pixel buffer to the main thread to be displayed, which is inefficient but does work. However, there isn't a synchronous way to communicate between the Worker and the main thread, so even if we buffered up input events in the main thread, there wouldn't be a way to get them to the Rust logic since that logic never yields control of the worker thread. There are asynchronous ways to hand off data, but that would require the Rust logic halting and resuming later, which the current structure does not allow. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<html> | ||
<head> | ||
<title>turtle via canvas</title> | ||
<meta charset="utf-8"/> | ||
<script type="text/javascript"> | ||
window.onload = (_) => { | ||
const exampleForm = document.getElementById("example"); | ||
const exampleInput = document.getElementById("example-name"); | ||
exampleForm.onsubmit = (_) => { | ||
const worker = new Worker('worker.js'); | ||
|
||
const canvas = document.getElementById('screen'); | ||
const ctx = canvas.getContext('2d'); | ||
|
||
worker.onmessage = (e) => { | ||
if (e.data['type'] === 'updateCanvas') { | ||
const img = new ImageData(e.data['pixels'], canvas.width, canvas.height); | ||
ctx.putImageData(img, 0, 0); | ||
} | ||
}; | ||
|
||
worker.postMessage({ | ||
'type': 'start', | ||
'exampleName': exampleInput.value, | ||
'width': canvas.width, | ||
'height': canvas.height | ||
}); | ||
|
||
return false; | ||
}; | ||
} | ||
</script> | ||
</head> | ||
<body> | ||
|
||
<form id="example"> | ||
<input type="text" placeholder="example name" value="randomcolors" id="example-name"/> | ||
<input type="submit"/> | ||
</form> | ||
|
||
<canvas id="screen" width="800px" height="600px" style="border: black 1px solid"></canvas> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,11 @@ | ||
#[macro_use] | ||
extern crate turtle; | ||
|
||
use turtle::Turtle; | ||
|
||
fn main() { | ||
let mut turtle = Turtle::new(); | ||
|
||
run_turtle!(|mut turtle| { | ||
for _ in 0..360 { | ||
// Move forward three steps | ||
turtle.forward(3.0); | ||
// Rotate to the right (clockwise) by 1 degree | ||
turtle.right(1.0); | ||
} | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this avoids a crash as the recently added color checking logic does its thing